【问题标题】:Django DEBUG=False won't upload files to STATIC_ROOTDjango DEBUG=False 不会将文件上传到 STATIC_ROOT
【发布时间】: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


【解决方案1】:

当使用 DEBUG=True 时,这意味着您处于开发端,因此您的本地计算机能够提供文件(媒体文件),但使用 DEBUG=False 时,它就像您现在处于部署端一样。

要从中提供媒体文件,您需要有一个存储桶(如 amazon S3)来存储这些文件并从那里获得服务。

因此,如果您的媒体文件在DEBUG=True 时工作正常,则说明一切正常。

现在您只需要一个存放它们的地方。

【讨论】:

  • 另外,如果使用 whitenoise,我认为我们不需要运行 collectstatic 命令,因为它可以解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 2020-10-27
  • 2015-04-11
  • 2018-06-05
  • 2016-11-26
  • 2019-09-14
  • 2019-06-01
相关资源
最近更新 更多