在 django 中处理图像上传表单:何时使用 save()、chunks() 和 clean_data?

发布于 2024-09-14 01:49:11 字数 1868 浏览 15 评论 0原文

我已使用以下代码成功上传了图像:

views.py

from django.conf.urls.defaults import *
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django import template
from django.template import RequestContext

from mysite.uploadr.forms import UploadFileForm

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            form.handle_uploaded_file(request.FILES['file'])
            return HttpResponse(template.Template('''
                        <html><head><title>Uploaded</title></head> <body>
                        <h1>Uploaded</h1>
                        </body></html>
                        '''
                        ).render( template.Context({}))
                    )
    else:  
        form = UploadFileForm()
    return render_to_response('upload.html', {'form': form}, context_instance=RequestContext(request))

forms.py

from django import forms
from settings import MEDIA_ROOT

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length = 50)
    file = forms.FileField()

    def handle_uploaded_file(self,file):
        #print type(file), "file.name=",file.name
        #print dir(file)
        destination = open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
        for chunk in file.chunks():
            destination.write(chunk)

我想更进一步,将图像与正在上传的用户关联起来。我看过一些例子,并且喜欢这篇文章中的技术:https://stackoverflow .com/questions/3348013/django-image-file-uploads。

我注意到他们的代码使用了 save() 和 clean_data。是否不需要像文档中的示例那样迭代块并写入目标文件夹?我必须使用cleaned_data吗?只是想找出最有效的上传文件的方法,我已经看到了很多不同的方法。非常感谢您的帮助。

I have successfully uploaded an image using the following code:

views.py

from django.conf.urls.defaults import *
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django import template
from django.template import RequestContext

from mysite.uploadr.forms import UploadFileForm

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            form.handle_uploaded_file(request.FILES['file'])
            return HttpResponse(template.Template('''
                        <html><head><title>Uploaded</title></head> <body>
                        <h1>Uploaded</h1>
                        </body></html>
                        '''
                        ).render( template.Context({}))
                    )
    else:  
        form = UploadFileForm()
    return render_to_response('upload.html', {'form': form}, context_instance=RequestContext(request))

forms.py

from django import forms
from settings import MEDIA_ROOT

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length = 50)
    file = forms.FileField()

    def handle_uploaded_file(self,file):
        #print type(file), "file.name=",file.name
        #print dir(file)
        destination = open(MEDIA_ROOT + '/images/'+file.name, 'wb+')
        for chunk in file.chunks():
            destination.write(chunk)

I'd like to go one step further and associate an image with the user who is uploading. I've seen a few examples and have taken a liking to the technique in this post: https://stackoverflow.com/questions/3348013/django-image-file-uploads.

I noticed that their code uses save() and cleaned_data. Is it not necessary to iterate thru the chunks and write to the destination folder like the examples in the documentation? Do I have to use cleaned_data? Just trying to figure out the most efficient means of uploading files, I 've seen so many different ways of doing this. Your help you be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

假扮的天使 2024-09-21 01:49:11

当文件大于 settings.FILE_UPLOAD_MAX_MEMORY_SIZE 时需要分块(django 1.2 中默认为 2.5M)

请查看 django.core.files.storage.FileSystemStorage 类。它的 save() 方法为您执行按块保存的工作并执行正确的文件锁定。

storage = FileSystemStorage(
                    location = '/var/www/site/upfiles', 
                    base_url = '/upfiles'
                  )


content = request.FILES['the_file']
name = storage.save(None, content) #you can use some suggested name instead of
                                   #None. content.name will be used with None
url = storage.url(name)   #<-- get url for the saved file

在旧版本的 django 中(例如 1.0),文件名的生成存在缺陷。它不断在文件名中添加_,并且如果重复上传相同的文件,上传的文件名会变得越来越长。这似乎在 1.2 版本中得到了修复。

Chunking is needed when file is bigger than settings.FILE_UPLOAD_MAX_MEMORY_SIZE (default 2.5M in django 1.2)

Take a look at django.core.files.storage.FileSystemStorage class. It's save() method does the chunk-wise saving job for you and does the proper file locking.

storage = FileSystemStorage(
                    location = '/var/www/site/upfiles', 
                    base_url = '/upfiles'
                  )


content = request.FILES['the_file']
name = storage.save(None, content) #you can use some suggested name instead of
                                   #None. content.name will be used with None
url = storage.url(name)   #<-- get url for the saved file

In the older versions of django (e.g in 1.0) there was a defect in generation of file names. It kept adding _ to file names and the uploaded file name got longer and longer if you upload the same file repeatedly. This seems to be fixed in version 1.2.

鲜肉鲜肉永远不皱 2024-09-21 01:49:11

通过直接访问 request.FILES['file'],您将绕过 UploadFileForm 正在执行的任何处理(您甚至不需要表单类来处理此类文件)。 form.cleaned_data['file'] 将访问已处理(如果添加了 clean 方法,则已清理)的表单数据。您还可以直接访问 request.POST 字典,而不是表单数据。除非您有充分的理由,否则最好使用清理后的表单数据。

在您提供的示例中,还使用了一个模型(这就是调用 save() 方法的模型),并且该模型的字段正在处理文件访问。如果您想将有关上传文件的信息保存在数据库中,那么就可以这样做。

您可以使用内置文件存储 API 来保存文件: http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage

此外,简单地使用用户指定的文件名调用 open(MEDIA_ROOT + '/images/'+file.name, 'wb+') 也不是一个好主意。这只是要求目录遍历或其他问题。

By accessing request.FILES['file'] directly, you're bypassing any processing that your UploadFileForm is doing (you don't even need a form class to handle files like that). form.cleaned_data['file'] would access the processed (and cleaned, if you added a clean method) form data. You could also access the request.POST dictionary directly, instead of the form data. Unless you have a good reason to, it's better to use the cleaned form data.

In the example you gave, there was also a model being used (which is what the save() method was being called on), and it was the model's field that was handling the file access. If you want to save information about your uploaded files in a database, that's the way to go.

You can use the built-in file storage API for saving files: http://docs.djangoproject.com/en/dev/ref/files/storage/#ref-files-storage.

Also, it's not a good idea to simply call open(MEDIA_ROOT + '/images/'+file.name, 'wb+'), with the user-specified file name. That's just asking for directory traversal or other issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文