Как переопределить файловое поле в views.py? - PullRequest
0 голосов
/ 09 мая 2011

У меня есть вид для редактирования документа:

@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

Теперь я хочу переопределить существующий файл (и автоматически удалить предыдущий файл). Как я могу это сделать?

1 Ответ

0 голосов
/ 10 мая 2011

Если я правильно понимаю, вы хотите заменить любой предыдущий файл в поле «файл» (тип данных FileField) модели документа. Это произойдет автоматически, если вы загрузите новый файл, используя форму. Вы видите другое поведение?

Автоматическое удаление предыдущих файлов зависит от версии Django, которую вы используете. Начиная с версии 1.3 (в настоящее время самая последняя) FileField не будет удалять файлы ( changelog ). В 1.2 и ранее FileField удалял файл из файловой системы при изменении и удалении. Поэтому, если вы измените или удалите экземпляр Model в 1.2, файл исчезнет. В версии 1.3 файл остается.

Вы делаете правильные вещи, звоня doc.file.delete(). Однако, если вы выполняете какую-либо массовую операцию с экземплярами модели, этого будет недостаточно. Для тестирования в 1.3 используйте AdminSite, чтобы выбрать несколько записей и выбрать выпадающий список. Пока записи исчезнут, файлы все еще будут существовать. Эти массовые операции QuerySet и любая операция удаления, которая пропускает вашу пользовательскую функцию document_edit (), оставят файлы позади. Лучше всего будет написать функцию удаления для всех типов данных FileField и прикрепить ее с помощью сигнала pre / post_delete . Если вам нужна помощь с этим, я предлагаю новый вопрос SO.

Другие вещи: Вы можете убрать свой код с помощью этой функции быстрого вызова

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

Вы используете Document.objects.get () три раза в своем опубликованном коде. Просто используйте приведенный выше ярлык один раз, а затем используйте переменную 'doc' во всех других местах

...