Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.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/Nginx-在提供超过一定大小的媒体文件时出现错误403_Python_Django_Nginx_Django Media - Fatal编程技术网

Python Django/Nginx-在提供超过一定大小的媒体文件时出现错误403

Python Django/Nginx-在提供超过一定大小的媒体文件时出现错误403,python,django,nginx,django-media,Python,Django,Nginx,Django Media,当用户上传图像时,它存储在项目目录中的媒体文件夹中。问题是,当他们想在网站上看到它时,nginx返回403禁止的错误(对于超过大约3 Mb的图像) 我将nginx.confclient\u max\u body\u size设置为8M http { ## # Basic Settings ## client_max_body_size 8M; ... 并且已在设置.py中更改了内存大小: FILE_UPLOAD_MAX

当用户上传图像时,它存储在项目目录中的
媒体
文件夹中。问题是,当他们想在网站上看到它时,nginx返回
403禁止的
错误(对于超过大约3 Mb的图像)

我将
nginx.conf
client\u max\u body\u size
设置为8M

http {

        ##
        # Basic Settings
        ##
        client_max_body_size 8M;
     ...
并且已在
设置.py中更改了内存大小:

FILE_UPLOAD_MAX_MEMORY_SIZE = 8388608
当我上传一个低于3 MB的图像时,没有问题,如果我上传的图像超过3 MB,我可以在
media
文件夹中看到它,但会引发错误,而不是提供图像:

GET https://example.com/media/images/dom.jpg 403 (Forbidden)
我注意到3 MB以下的文件具有不同的权限:

-rw-r--r-- 1 django www-data    4962 Jul 19 19:51 61682_3995232_IMG_01_0000.jpg.150x84_q85_crop.jpg
-rw-r--r-- 1 django www-data 1358541 Jul 20 09:32 byt.jpg
-rw------- 1 django www-data 3352841 Jul 20 09:32 dom.jpg
-rw-r--r-- 1 django www-data    5478 Jul 19 20:10 downloasd.jpeg.150x84_q85_crop.jpg
-rw-r--r-- 1 django www-data    3225 Jul  9 22:53 images.jpeg.100x56_q85_crop.jpg
-rw-r--r-- 1 django www-data    6132 Jul 19 20:00 NorthYorkHouse2.JPG.150x84_q85_crop.jpg
你知道问题出在哪里吗

编辑:

查看

class NehnutelnostUploadImagesView(LoginRequiredMixin, ExclusiveMaklerDetailView, DetailView):
    template_name = "nehnutelnosti/nehnutelnost_image_upload.html"
    model = Nehnutelnost

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = ImageUploadForm(self.request.POST, self.request.FILES, nehnutelnost=self.object)
        if form.is_valid():
            nehnutelnost_image = form.save()
            images_count = self.object.images.count()

            data = {'is_valid': True, 'row_html': image_row_renderer(nehnutelnost_image, self.request),
                    'name': nehnutelnost_image.image.name, 'url': nehnutelnost_image.image.url,}
        else:
            images_count = self.object.images.count()

            data = {'is_valid': False, 'errors': form.errors, 'images_count': images_count}
        return JsonResponse(data)

    def get_context_data(self, **kwargs):
        context = super(NehnutelnostUploadImagesView, self).get_context_data(**kwargs)
        context['images'] = self.object.images.all()
        context['podorys'] = self.object.podorys
        return context
我们使用插件上传图片

$(function () {

            $(".js-upload-photos").click(function () {
                $("#fileupload").click();
            });

            $("#fileupload").fileupload({
                dataType: 'json',
                sequentialUploads: true, /* 1. SEND THE FILES ONE BY ONE */
                start: function (e) {  /* 2. WHEN THE UPLOADING PROCESS STARTS, SHOW THE MODAL */
                    $(".modal").modal().show();
                },
                stop: function (e) {  /* 3. WHEN THE UPLOADING PROCESS FINALIZE, HIDE THE MODAL */
                    $(".modal").modal().hide();
                    $(".modal-backdrop").hide();

                },
                {#                TODO Chrome bug?#}
                progressall: function (e, data) {  /* 4. UPDATE THE PROGRESS BAR */
                    var progress = parseInt(data.loaded / data.total * 100, 10);
                    var strProgress = progress + "%";
                    $(".progress-bar").css({"width": strProgress});
                    $(".progress-bar").text(strProgress);
                },
                done: function (e, data) {
                    if (data.result.is_valid) {

                        $(".gridly").prepend(
                            data.result.row_html
                        )


                    }
                    var message = data.result.message;
                    addMessage('success', message);
                    var errors = data.result.errors;
                    if (errors) {
                        $.each(errors, function (fieldname, error_messages) {
                            $.each(error_messages, function (_, message) {
                                addMessage('danger', message);
                            })
                        })
                    }
                    var images_count_span = $('#images_count');
                    var images_count = data.result.images_count;
                    images_count_span.text(' - ' + images_count);
                    makegrid();

                }

            });
从:

默认情况下,如果上载的文件小于2.5 MB,Django将在内存中保存上载的全部内容

更具体地说,它意味着较小的文件使用,而较大的文件使用。后者使用
tempfile
创建一个只有用户才能访问的临时文件

在完成所有表单和模型验证以及所有操作之后,实际保存是通过
FileSystemStorage.\u save
方法执行的。此时,该文件仍然是
临时上载文件
或内存中的
加载文件
,具体取决于其大小

现在,临时上传文件是一个实际文件,由
tempfile
创建,只有用户权限

save方法做了一件聪明的事情:如果给定一个临时文件(即,
if hasattr(content,'temporary\u file\u path')
),它会移动它而不是复制它。这意味着它保留其仅限用户的权限,并且仍然无法被
www-data
读取

InMemoryUploadedFile不会出现这个问题,它只会使用进程拥有的任何默认权限(在您的情况下,用户和组的读/写权限)

如何修复?

如果请求,存储对象可以设置权限。对于默认存储对象,可以使用设置。这里,

…应该这样做


(这对于django用户是R/W,对于nginx是只读的)

您用来保存文件的代码是什么?@spectras我已经在问题的底部添加了代码。我也有同样的问题,但我是django的新手。我不明白我必须把“文件上传权限=0o640”放在哪里。我把它放在settings.py(如果是,放在哪里?)或我上传应用的模型中@Milano@MassimilianoMoraca如您所见,思百吉添加了一个指向源的链接。如果你点击链接文件“上传权限”,你可以看到它应该在settings.py中。谢谢@Milano,我已经看到了,但是我的dubt在settings.py中的位置,我必须把它放在那里……不管你把它放在哪里(除非你在上面的某个地方覆盖它)。问题出在别的地方。如果是生产服务器,您应该检查您的服务器限制,例如NGINX和Gunicorn。@spectras我的NGINX用户是
www-data
。当添加
文件上传权限=0o2755
时,它运行良好
FILE_UPLOAD_PERMISSIONS=0o640