Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该将图像上传到Django中的静态目录吗?_Python_Django_File Upload_Permissions_Static Files - Fatal编程技术网

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
来检查权限吗?是的,如果您只允许用户查看自己的文件,这可能是最好的方法。