如何解决当 Cpanel 上的调试为 False 时,Django 媒体文件未加载
我试图展示我的媒体文件一个多星期,并尝试了所有 stackoverflow 解决方案,但一无所获。我的项目托管在 Cpanel 上,我尝试为媒体提供绝对路径,尝试将它们放在 public_html 文件夹中,什么也没有。另外我的静态文件没有问题,但媒体文件甚至没有显示在开发人员工具的源代码中(在正常情况下应该有一个),当调试为真时,它工作得很好,但当调试为假时,它确实如此不是。请问有什么想法吗?
我的 settings.py 的一部分
import os
from django.contrib.messages import constants as messages
from decouple import config
# Build paths inside the project like this: os.path.join(BASE_DIR,...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# Security WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')
# Security WARNING: don't run with debug turned on in production!
DEBUG = False
CSRF_COOKIE_SECURE = config('CSRF_COOKIE_SECURE')
SESSION_COOKIE_SECURE = config('SESSION_COOKIE_SECURE')
MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware','django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','whitenoise.middleware.WhiteNoiseMiddleware'
]
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesstorage'
STATICFILES_Dirs = [
os.path.join(BASE_DIR,"static")
]
STATIC_ROOT = os.path.join(BASE_DIR,'assets')
CKEDITOR_UPLOAD_PATH = 'uploads/'
MEDIA_URL ='/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
INTERNAL_IPS = ['127.0.0.1','::1','0.0.0.0']
项目 urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/',admin.site.urls),path('',include('main.urls')),path('panier/',include('cart.urls',namespace='cart')),path('commande/',include('orders.urls',namespace='orders')),path('ckeditor/',include('ckeditor_uploader.urls')),path('coupon/',include('coupons.urls',namespace='coupons'))
]
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
if settings.DEBUG == True:
import debug_toolbar
urlpatterns += [path('__debug__/',include(debug_toolbar.urls)),]
我的一些模型
from django.db import models
from django.urls import reverse
from django.utils import timezone
import datetime
from django.db.models import F
from django.conf import settings
import os
from django.utils.deconstruct import deconstructible
from django.core.validators import MinValueValidator
from ckeditor.fields import RichTextField
from django.utils.safestring import mark_safe
PRODUCT_STATUS = (
('N','Nouveau'),('P','Promotion'),('S','Sans Status')
)
@deconstructible
class PathAndRename(object):
def __init__(self,sub_path):
self.path = sub_path
def __call__(self,instance,filename):
filename = 'product_{0}_{1}'.format(instance.user.id,filename)
# return the whole path to the file
return os.path.join(self.path,filename)
def solution_directory_path(instance,filename):
date_fields = str(datetime.date.today()).split('-')
year = date_fields[0]
month = date_fields[1]
day = date_fields[2]
# file will be uploaded to MEDIA_ROOT/solutions/YEAR/MONTH/DAY/solution_id_<filename>
solution_sub_path = 'solutions/{0}/{1}/{2}/solution_{3}_{4}'.format(year,month,day,instance.id,filename)
solution_full_path = os.path.join(settings.MEDIA_ROOT,solution_sub_path)
if os.path.exists(solution_full_path):
os.remove(solution_full_path)
return solution_sub_path
def product_directory_path(instance,filename):
date_fields = str(datetime.date.today()).split('-')
year = date_fields[0]
month = date_fields[1]
day = date_fields[2]
# file will be uploaded to MEDIA_ROOT/produits/YEAR/MONTH/DAY/produit_<produit_id>_<filename>
product_sub_path = 'produits/{0}/{1}/{2}/product_{3}_{4}'.format(year,instance.product_id,filename)
product_full_path = os.path.join(settings.MEDIA_ROOT,product_sub_path)
if os.path.exists(product_full_path):
os.remove(product_full_path)
return product_sub_path
def product_directory_path_second_picture(instance,filename):
date_fields = str(datetime.date.today()).split('-')
year = date_fields[0]
month = date_fields[1]
day = date_fields[2]
# file will be uploaded to MEDIA_ROOT/produits/YEAR/MONTH/DAY/produit_<produit_id>_<filename>
product_sub_path = 'produits/{0}/{1}/{2}/product_{3}_photo_2_{4}'.format(year,product_sub_path)
if os.path.exists(product_full_path):
os.remove(product_full_path)
return product_sub_path
def product_file_directory_path(instance,filename):
date_fields = str(datetime.date.today()).split('-')
year = date_fields[0]
month = date_fields[1]
day = date_fields[2]
# file will be uploaded to MEDIA_ROOT/produits/YEAR/MONTH/DAY/produit_<produit_id>_<filename>
product_sub_path = 'fichers/{0}/{1}/{2}/product_{3}_{4}'.format(year,product_sub_path)
if os.path.exists(product_full_path):
os.remove(product_full_path)
return product_sub_path
# custom product manager : have to use it for search filtering
class ProductManager(models.Manager):
def get_queryset(self):
return super(ProductManager,self).get_queryset()\
.filter(stock__gte=1,available=True)
class Solution(models.Model):
name = models.CharField( max_length=50)
slug = models.SlugField( max_length=70)
photo = models.ImageField(verbose_name='Photo de la solution',upload_to=solution_directory_path,blank=True)
photo_2 = models.ImageField(verbose_name='Photo 2 de la solution',blank= True)
description = RichTextField(verbose_name='Text en plus',blank= True,null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("produit",args=[self.slug])
class Category(models.Model):
name = models.CharField(max_length=200,db_index=True)
slug = models.SlugField(max_length=200,unique=True)
class Meta:
ordering = ('name',)
verbose_name = 'Catégorie'
verbose_name_plural = 'Catégories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("product-by-cat",args = [self.slug])
class Product(models.Model):
product_id = models.CharField(max_length= 50,blank=False,null= False,unique=True,default='',verbose_name='Numéro du Produit')
name = models.CharField(max_length=50,verbose_name = 'Nom du Produit',db_index=True)
slug = models.SlugField(max_length=70,verbose_name= 'Slug')
solution = models.ForeignKey(Solution,on_delete=models.SET_NULL,verbose_name='Solution',null=True)
category = models.ForeignKey(Category,on_delete= models.CASCADE,related_name="products",verbose_name='Catégorie')
sub_title = models.CharField(max_length=100,verbose_name=("Sous titre"),blank= True)
description = RichTextField(verbose_name='Description',null=True)
sup_info = RichTextField(verbose_name='informations Supplémentaires',null=True)
photo = models.ImageField(verbose_name='Photo du Produit',upload_to= product_directory_path,blank=True)
photo_2 = models.ImageField(verbose_name='Photo du Produit 2',upload_to= product_directory_path_second_picture,blank=True)
file_1 = models.FileField(verbose_name='Fiche Technique',upload_to=product_file_directory_path,blank= True)
price = models.DecimalField(verbose_name='Prix',max_digits=10,decimal_places=2,validators = [MinValueValidator(0)],null=False)
available = models.BooleanField(verbose_name='disponibilité',default=True)
status = models.CharField(choices= PRODUCT_STATUS,max_length=50,default='S',null = False,verbose_name="Status")
created = models.DateTimeField(verbose_name='Date de Création',auto_Now_add=True)
updated = models.DateTimeField(verbose_name='Date de dernière mise à jour',auto_Now=True)
stock = models.PositiveIntegerField(verbose_name='Stock',validators= [MinValueValidator(0)],default=0,null=False )
objects = models.Manager() # The default manager.
show = ProductManager() # Our custom manager
class Meta:
ordering = ('name',)
verbose_name = 'Produit'
verbose_name_plural = 'Produits'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("produits",args=[self.slug])
def get_description(self):
return mark_safe(self.description)
def get_sup_info(self):
return mark_safe(self.sup_info)
class ContactForm(models.Model):
name = models.CharField(verbose_name='Nom complet',max_length=100)
phone = models.CharField(verbose_name="Téléphone",max_length=25)
email = models.EmailField(verbose_name="Email",null=True,blank = True)
subject = models.CharField(verbose_name="Sujet",blank=False)
message = models.TextField(verbose_name="Sujet",null=False)
date_sent = models.DateTimeField(verbose_name="Date",auto_Now_add=True)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Formulaire de Contact'
class Post(models.Model):
titre = models.CharField(max_length=200)
slug = models.SlugField(max_length=100)
intro = models.CharField(max_length=200,blank=True)
image = models.ImageField(verbose_name='Image',upload_to='slides/',blank= True)
text = RichTextField(verbose_name='Article',null=True)
created_date = models.DateTimeField(default=timezone.Now)
def __str__(self):
return self.titre
解决方法
您不能使用白噪声为您的媒体文件提供服务:https://github.com/evansd/whitenoise/issues/62 您需要将您的服务器配置为让 apache 或 nginx 或类似的东西为您的媒体目录中的这些媒体文件提供服务。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。