How to override filefield in views.py?
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 开发者_C百科= '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?
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
精彩评论