【发布时间】:2021-08-23 14:30:08
【问题描述】:
我试图让用户能够在我使用Django 创建的网站上上传图像,并且在使用DEBIG=True 运行时图像上传正常,但问题是当DEBUG=False 图像文件不不要上传到MEDIA_ROOT,而是上传到STATIC_DIRS。此外,即使是在执行python manage.py collectstatic 之后已经在MEDIA_ROOT 中的文件也不会加载到模板中,并且图像 URL 会给出404 Page Not Found 错误。
仍然提供 CSS 和 JS 文件,因此这意味着只有媒体 url 不工作。
以下是我正在使用的代码。
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('Home.urls')),
path('account/', include('Account.urls')),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
注意我使用whitenoise作为存储后端。
这是用于上传文件的型号代码。
@deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
filename = '{}.{}'.format(uuid4().hex, ext)
return os.path.join(self.path, filename)
rename_pp = PathAndRename('img/profile-pictures')
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
avatar = models.ImageField(upload_to=rename_pp, blank=True, null=True, default='img/profile-pictures/default-profile-pic.png')
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
image = Image.open(self.avatar.path)
if image.width > 100 or image.height > 100:
output_size = (100, 100)
image.thumbnail(output_size, Image.ANTIALIAS)
image.save(self.avatar.path, file_quality=100)
【问题讨论】:
-
为什么用户上传的文件会被上传到
STATIC_ROOT?用户上传的文件是 media 文件并上传到MEDIA_ROOT,因此查看您的代码,您将获得正确的行为。注意:一个不使用静态标签来显示媒体文件,一个简单地使用model_instance.field.url,因此你会写:{{ profile.avatar.url }}
标签: python django file-upload imagefield