如何覆盖views.py中的文件字段?

发布于 2024-11-06 17:21:48 字数 2217 浏览 0 评论 0原文

我可以查看文档编辑:

@login_required
def document_edit(request, doc_id):
    try:
        doc = Document.objects.get(id=doc_id)
    except Document.DoesNotExist:
        raise Http404
    form = DocumentForm(instance=doc)
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES, instance=doc)
        if form.is_valid():
            if request.POST.get('cancel'):
               return HttpResponseRedirect('/')
            if request.POST.get('delete'):
                document = Document.objects.get(id=doc_id)
                document.file.delete()
                document.delete()
                return HttpResponseRedirect('/')
            else:
                form.save(author=request.user)
                text = "Document edited!"
                return render_to_response('message.html', {'text' : text}, context_instance = RequestContext(request))
        else:
            return render_to_response('document_edit.html', {'form':form,}, context_instance = RequestContext(request))
    else:
        form = DocumentForm(instance=Document.objects.get(id=doc_id))
        return render_to_response('document_edit.html', {'form':form, 'doc':doc,}, context_instance = RequestContext(request))

以及 forms.py 中的此表单:

class DocumentForm(ModelForm):
    file = forms.FileField(label = 'file', required=True, error_messages={'required' : 'required!','empty': "this file is empty!"})
    title = forms.CharField(label = 'title', widget = forms.TextInput(attrs={'size': 93,}), error_messages={'required': 'required!'})
    description = forms.CharField(label = 'description', widget = forms.Textarea(attrs={'rows': 10, 'cols': 120,}), error_messages={'required': 'required!'})
    editable = forms.BooleanField(label='Document editable?', widget=forms.RadioSelect(choices=YES_OR_NO), required=False, initial=True)
    class Meta:
        model = Document
        exclude = ('author',)

    def save(self, author, commit=True):
        document=ModelForm.save(self,commit=False)
        document.author = author
        if commit:
            document.save()
        return document

现在我希望能够覆盖现有文件(并自动删除以前的文件)。我怎样才能做到这一点?

I have view to document edit:

@login_required
def document_edit(request, doc_id):
    try:
        doc = Document.objects.get(id=doc_id)
    except Document.DoesNotExist:
        raise Http404
    form = DocumentForm(instance=doc)
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES, instance=doc)
        if form.is_valid():
            if request.POST.get('cancel'):
               return HttpResponseRedirect('/')
            if request.POST.get('delete'):
                document = Document.objects.get(id=doc_id)
                document.file.delete()
                document.delete()
                return HttpResponseRedirect('/')
            else:
                form.save(author=request.user)
                text = "Document edited!"
                return render_to_response('message.html', {'text' : text}, context_instance = RequestContext(request))
        else:
            return render_to_response('document_edit.html', {'form':form,}, context_instance = RequestContext(request))
    else:
        form = DocumentForm(instance=Document.objects.get(id=doc_id))
        return render_to_response('document_edit.html', {'form':form, 'doc':doc,}, context_instance = RequestContext(request))

and this form in forms.py:

class DocumentForm(ModelForm):
    file = forms.FileField(label = 'file', required=True, error_messages={'required' : 'required!','empty': "this file is empty!"})
    title = forms.CharField(label = 'title', widget = forms.TextInput(attrs={'size': 93,}), error_messages={'required': 'required!'})
    description = forms.CharField(label = 'description', widget = forms.Textarea(attrs={'rows': 10, 'cols': 120,}), error_messages={'required': 'required!'})
    editable = forms.BooleanField(label='Document editable?', widget=forms.RadioSelect(choices=YES_OR_NO), required=False, initial=True)
    class Meta:
        model = Document
        exclude = ('author',)

    def save(self, author, commit=True):
        document=ModelForm.save(self,commit=False)
        document.author = author
        if commit:
            document.save()
        return document

Now i want possibility to override existed file (and automatically deleting previous file). How can i do that?

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

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

发布评论

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

评论(1

壹場煙雨 2024-11-13 17:21:48

如果我理解正确,您正在寻找替换文档模型的“文件”字段(FileField 数据类型)中的任何先前文件。如果您使用表单上传新文件,这将自动发生。您是否看到不同的行为?

自动删除以前的文件取决于您使用的 Django 版本。从 1.3(当前最新)开始,FileField 将不会删除任何文件 (变更日志)。在 1.2 及之前的版本中,FileField 会在更改和删除时从文件系统中删除文件。因此,如果您在 1.2 中更改或删除 Model 实例,该文件就会消失。在 1.3 下,文件保留。

通过调用 doc.file.delete(),您正在做正确的事情。但是,如果您对模型实例执行任何类型的批量操作,这还不够。要在 1.3 中进行测试,请使用 AdminSite 选择多个记录并选择删除下拉列表。虽然记录将消失,但文件仍然存在。这些批量 QuerySet 操作和任何跳过自定义 document_edit() 函数的删除操作都会留下文件。最好的选择是为所有 FileField 数据类型编写一个删除函数,并将其附加到 pre /post_delete 信号。如果您需要这方面的帮助,我建议一个新的问题。

其他事项:您可以使用此快捷功能整理您的代码

from django.shortcuts import get_object_or_404
doc = get_object_or_404(Document, id=doc_id)

您在发布的代码中使用了 Document.objects.get() 三次。只需使用上面的快捷方式一次,然后在所有其他位置使用“doc”变量

If I understand correctly, you are looking to replace any previous file in the 'file' field (a FileField datatype) of a Document Model. That will happen automatically if you upload a new file using the form. Are you seeing different behavior?

Automatically deleting the previous files depends on the Django version you are using. As of 1.3 (currently the most recent) FileField will not delete any files (changelog). In 1.2 and prior, the FileField would remove the file from the filesystem on change and on delete. So if you change or delete the Model instance in 1.2, the file goes away. Under 1.3, the file stays.

You are doing the right thing by calling doc.file.delete(). However, if you do any sort of bulk operation on model instances, this won't be enough. To test in 1.3, use the AdminSite to select multiple records and select the delete dropdown. While the records will be gone, the files will still exist. These bulk QuerySet operations and any delete operation that skips your custom document_edit() function will leave behind the files. Your best bet will be to write a removal function for all FileField datatypes and attach it with a pre/post_delete signal. If you need help with this, I suggest a new SO Question.

Other things: You can tidy your code with this shortcut function

from django.shortcuts import get_object_or_404
doc = get_object_or_404(Document, id=doc_id)

You use Document.objects.get() three times in your posted code. Just use the above shortcut once and then use the 'doc' variable in all other locations

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