django - Django 管理员在生产中上传图片
问题描述
我通过我生产的管理界面上传的图像无法找到,尽管它存在于服务器上。它在开发中加载良好。我使用 Django Image-kit 来调整上传图像的大小。
图片未显示在网站上,如果我按照图片网址进行操作,我会得到
<h1>Not Found</h1>
<p>The requested URL /media/CACHE/images/references/<reference-name>/<image-name>/211b0022f8a2baad7cdc527711dcb.jpg was not found on this server.</p>
上传的图像未添加到我的静态文件中,这些文件正确显示。
我的模型如下所示:
def generate_unique_slug(instance, field):
original = slugify(field)
unique = original
numb = 1
while instance.objects.filter(slug=unique).exists():
unique = f'{original}-{numb}'
numb += 1
return unique
def reference_main_image_path(instance, filename):
sub_folder = instance.slug
return f'references/{sub_folder}/{filename}'
class Reference(models.Model):
title = models.CharField(max_length=60)
description = models.TextField(max_length=2000)
slug = models.SlugField(max_length=12, unique=True, blank=True)
main_image = models.ImageField(
upload_to=reference_main_image_path, default='default.png')
main_thumbnail = ImageSpecField(source='main_image',
processors=[ResizeToFill(540, 300)],
format='JPEG',
options={'quality': 80},)
tags = TaggableManager()
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if self.slug:
if slugify(self.title) != self.slug:
self.slug = generate_unique_slug(Reference, self.title)
else:
self.slug = generate_unique_slug(Reference, self.title)
super().save(*args, **kwargs)
我的view.py
:
def reference(request):
context = {
'references': Reference.objects.all(),
}
return render(request, 'home/references.html', context)
在“html”代码中,我像这样“调用”图像:
<img src="{{ reference.main_thumbnail.url }}">
我的settings.py
静态和媒体变量如下所示:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
我跑了manage.py collectstatic
我upload_to
应该改变吗?或者我如何告诉 Django 在“收集静态”时查看文件夹,然后将 html 更改为查看静态文件夹?
我觉得很奇怪 image-kit 的文档应该只考虑“开发”还是我错过了什么?
谢谢!
编辑:我在生产中使用 gunicorn 和 Nginx,但如前所述,我的静态文件加载得很好。
编辑 2:Nginx 配置:
server {
server_name <server_names>;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/<user>/projects/<project>/<project>;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
我遗漏了一些 certbot SSL 配置。
编辑3 urls.py
::
from django.urls import path
from . import views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('', views.home, name='home'),
path('ydelser/', views.service, name='service'),
path('referencer/', views.reference, name='reference'),
path('kontakt/', views.contact, name='contact'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
解决方案
要使用 nginx 提供媒体文件,您应该添加类似于以下内容的适当位置static
:
location /static/ {
root /home/<user>/projects/<project>/<project>;
}
location /media/ {
root /home/<user>/projects/<project>/<project>;
}
就像你在 django 中所做的那样:
...
STATIC_URL = '/static/'
...
MEDIA_URL = '/media/'
但是,如果您不想使用 nginx 提供媒体文件(推荐)并且仍想使用 django 提供媒体文件(不推荐),请确保该行
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
当 DEBUG=False 时启用。
请注意,您不应将媒体文件视为静态文件——它们在逻辑上是不同的。虽然静态文件属于并随您的解决方案/项目一起提供,但媒体文件不属于您的项目,通常由用户制作。
ps
如果您已在本地将一些文件上传到您的网站,则它们的位置与此相对应:
def reference_main_image_path(instance, filename):
sub_folder = instance.slug
return f'references/{sub_folder}/{filename}'
class Reference(models.Model):
...
main_image = models.ImageField(
upload_to=reference_main_image_path, default='default.png')
如果您没有将它们(位于上面配置的文件夹中的硬盘驱动器上的文件)复制到 prod 服务器 - 它们将不会显示。如果需要,手动复制它们并将目标文件夹与 nginx 位置匹配。
推荐阅读
- preact - preact-cli 项目在添加 react-ga 时显示“无法解析 'react'”(别名问题)
- c++ - How can I check if Google services are blocked for my current user?
- javascript - How to stop the slider from resetting to the left side on mouse release (react-spring react-use-gesture)
- javascript - 如何申请 forEach();
- python - 我可以编写一个可以为 x 行重复图表的程序吗
- html - 使用 flexbox 在 li 标签中定义锚标签
- macos - 如何允许 Github Action 的 Mac 屏幕录制 (Testcafe)
- mongodb - 我需要帮助从 mongodb 获取聚合数据 - 有些在数组中,有些不在数组中
- jmeter - jmeter restful api在报告中获取连接关闭、错误请求和警告
- wordpress - 在产品页面上输入姓名和电子邮件,并在结帐页面上保留输入数据