Python 我应该将图像上传到Django中的静态目录吗?
我有一个包含图像字段的模型Python 我应该将图像上传到Django中的静态目录吗?,python,django,file-upload,permissions,static-files,Python,Django,File Upload,Permissions,Static Files,我有一个包含图像字段的模型 from django.db import models from django.contrib.auth.models import User class Customer(models.Model): user = models.ForeignKey(User) name = models.CharField(max_length=127) logo = models.ImageField(upload_to='customer/log
from django.db import models
from django.contrib.auth.models import User
class Customer(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=127)
logo = models.ImageField(upload_to='customer/logo', null=True, blank=True)
def __str__(self):
return self.name
在我看来,我从指定的url下载图像并将其存储在图像字段中。对于测试,我使用测试用户作为外键
import json
import urllib.request
from django.core.files.base import ContentFile
from django.http import HttpResponse
from django.contrib.auth.models import User
from customer.models import Customer
def create(request):
values = json.loads(request.body.decode('utf-8'))
values['user'] = User.objects.get(id=1)
values['logo'] = ContentFile(urllib.request.urlopen(values['logo']).read(),
'test.png')
model = Customer.objects.create(**values)
return HttpResponse('Created customer with ' + str(values))
图像按预期上传到customer/logo/test.png
。现在,如何在前端显示这些图像?我可以将它们保存到静态文件目录中,但只有相关用户才能访问它
(顺便说一句,Django管理界面显示有一个为
Customer
对象上传的文件。但是它链接到http://localhost:8000/admin/customer/customer/20/customer/logo/test.png
位置错误,导致找不到页面。)文件字段和图像字段的文件是相对于设置上载的。MEDIA\u ROOT
应该可以通过附加到设置中的相同相对文件名访问。MEDIA\u URL
。这就是为什么您的管理界面指向错误的url。出于安全原因,它们应该不同于STATIC\u ROOT
和STATIC\u URL
,否则Django将引发配置错误
这不会阻止用户访问他们不应该看到的文件,如果他们知道或可以猜测url的话。为此,您需要通过Django而不是您选择的web服务器来提供这些私有文件。基本上,您需要在web根目录级别下指定一个私有目录,如果用户有权查看文件,则需要加载这些文件。例如:
from django.core.files.storage import FileSystemStorage
PRIVATE_DIR = os.path.join(ROOT_DIR, 'web-private')
fs = FileSystemStorage(location=PRIVATE_DIR)
class Customer(models.Model):
logo = models.ImageField(upload_to='customer/logo', storage=fs, null=True, blank=True)
在您看来,您必须提供此文件。我当前项目上的一个自定义应用程序使用以下功能发送静态文件:
import mimetypes
from django.http import HttpResponse # StreamingHttpResponse
from django.core.servers.basehttp import FileWrapper
def send_file(file):
"""
Send a file through Django without loading the whole file into
memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB.
"""
filename = file.name
if settings.PRIVATE_MEDIA_USE_XSENDFILE:
# X-sendfile
response = HttpResponse()
response['X-Accel-Redirect'] = filename # Nginx
response['X-Sendfile'] = filename # Apache 2, mod-xsendfile
# Nginx doesn't overwrite headers, but does add the missing headers.
del response['Content-Type']
else:
# Can use django.views.static.serve() method (which supports if-modified-since),
# but this also does the job well, as it's mainly for debugging.
mimetype, encoding = mimetypes.guess_type(filename)
response = HttpResponse(FileWrapper(file), content_type=mimetype)
response['Content-Length'] = os.path.getsize(filename)
return response
然后在视图中使用发送文件(customer.logo)
Django>=1.5应使用新的StreamingHttpResponse
而不是HttpResponse
非常感谢!我可以正常使用request.user
来检查权限吗?是的,如果您只允许用户查看自己的文件,这可能是最好的方法。