【发布时间】:2021-06-28 14:43:44
【问题描述】:
我试图展示我的媒体文件一个多星期,并尝试了所有 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, month, day,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, month, day,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_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, month, day,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
# 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', upload_to=solution_directory_path, 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', default='', 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', blank= True, null=True)
sup_info = RichTextField(verbose_name='Informations Supplémentaires', blank= True, 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)], blank=False, null=False)
available = models.BooleanField(verbose_name='Disponibilité', default=True)
status = models.CharField(choices= PRODUCT_STATUS, max_length=50, default='S' , blank=False, 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, blank=False, 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", max_length=50, blank=False)
message = models.TextField(verbose_name="Sujet", blank=False, 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', blank= True, null=True)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.titre
【问题讨论】:
标签: django deployment cpanel django-media