Загрузка файла Django: имя файла не прилипает - PullRequest
2 голосов
/ 30 января 2011

Я загружаю файлы и храню метаданные в БД.Частью метаданных является само имя файла.Однако, где-то внизу, имя файла, похоже, не сохраняется!Я буду вставлять только те части кода, которые, на мой взгляд, являются соответствующими.

class UploadFile(models.Model):
   ...
    theFile = models.FileField(upload_to = "Genius/Uploads/", null = True)
    filename = models.CharField(max_length = 50, blank = True, null = False)

class UploadFileForm(ModelForm):
    class Meta:
        model = UploadFile
        fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename


def files_upload(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            form.filename = request.FILES['theFile'].name # TODO: sanitize!
            # form.filename = 'foo'
            form.save()
            return HttpResponseRedirect('/files/upload/successful/')
        else:
            form = UploadFileForm()
        return render_to_response('files/upload_file.html', { 'form': form })

Я проверил значение request.FILES ['theFile']. Name до и после сохранения формы.По какой-то причине он не поврежден, но, кажется, никогда не попадает в БД.

Ответы [ 3 ]

2 голосов
/ 30 января 2011

Это потому, что form.filename - это поле формы, а не значение, которое оно будет сохранять.

Вы ищете что-то вроде этого:

class UploadFileForm(ModelForm):
    def save(self, commit=True):
        instance = ModelForm.save(self, commit=False)
        instance.filename = self.files['theFile'].name

        if commit:
            instance.save()

        return instance

    class Meta:
        model = UploadFile
        fields = ('title', 'theFile', 'date_uploaded',) # Don't prompt for filename

Альтернативное решение:

upload_file = form.save(commit=False)
upload_file.filename = request.FILES['theFile'].name
upload_file.save()
1 голос
/ 30 января 2011

Значения полей формы не доступны через атрибуты формы.Таким образом, установка 'form.filename' не устанавливает значение, которое будет сохранено в поле имени файла.Вместо этого установите значение для экземпляра, возвращаемого функцией form.save ().

upload_file = form.save(commit=False) 
upload_file.filename = filename
upload_file.save() 
0 голосов
/ 30 января 2011

Я просто хотел добавить, что в будущем вы могли бы попытаться не включать такую ​​бизнес-логику в форму модели. Хотя WoLpH является правильным и является прекрасным примером того, как обрабатывать дополнительную обработку экземпляра модели с помощью ModelForm, конкретные случаи зависимости полей от данных других полей обрабатываются в Model, Form и ModelForm API через их уважаемые clean() методы и упоминается в нескольких местах в официальных справочных документах (вот один на формах , хотя то же самое относится и к Model и ModelForm API) .

В вашем случае это будет означать:

import os

class UploadFile(models.Model):

     # ...

     def clean(self):
          # Field data has already been populated by this point.
          # Note that `FieldFile` inherits from `File` and that
          # `File.name` is actually the full path to the file
          # so we need to get the base path component sans the extension

          path, extension = os.path.splitext(self.thefile.file.name)
          self.filename = os.path.basename(path)

И это все! Если вы правильно установите атрибут editable в полях модели, вы обнаружите, что вы можете положиться на Django, чтобы автоматически генерировать ModelForm для модели UploadFile. Это означает, что вам не нужно определять ModelForm для общего создания, обновления представлений или ModelAdmin вашей модели, и это меньше строк кода для управления!

Общее практическое правило заключается в том, что вы дважды подумаете о том, является ли переопределенное поведение по умолчанию оправданным или автономным, особенно когда вы работаете в дальнем конце цепочки бизнес-логики, в противном случае вы можете почувствовать гнев неожиданных провалов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...