Как получить доступ к файлу Django forms.FileField (*не models.FileField*)?

У меня Джанго 1.7.

У меня есть следующая модель формы:

class DeckCreateForm(forms.ModelForm):
    csv_file = forms.FileField(required=False)
    class Meta:
        model = Deck
        fields = ['title', 'description']

Обратите внимание, что поле файла не является частью модели (и я хотел бы оставить его таким). Это поле файла предназначено для предоставления альтернативных средств построения колоды модели.

Я хотел бы знать, как получить доступ к загруженному файлу. Я посмотрел в своем медиа-каталоге, но его там нет. Я попытался добавить «upload_to» в конструктор csv_file, но получил ошибку:

TypeError: __init__() got an unexpected keyword argument 'upload_to'

РЕДАКТИРОВАТЬ:

Я хотел бы знать, как заставить это работать с представлением создания общего класса, которое использует приведенную выше форму модели - в views.py у меня есть:

class DeckCreateView(CreateView):
    model = Deck
    form_class = DeckCreateForm
    template_name = 'deck_create.html'

В частности, как мне изменить что-то вроде http://docs.djangoproject.com/en/1.7/topics/http/file-uploads для работы с представленным выше представлением на основе классов. Мой файл urls.py:

urlpatterns = patterns(
    ...
    url(r"^deck/create/$", views.DeckCreateView.as_view(), name="deck-create"),
    ...
)

Есть ли метод, который я могу переопределить в DeckCreateView для обработки загрузки файла?


person David Simic    schedule 03.01.2015    source источник
comment
https://docs.djangoproject.com/en/1.7/topics/http/file-uploads/ это довольно хорошо объясняет процесс.   -  person kviktor    schedule 03.01.2015
comment
kviktor - Я отредактировал вопрос в ответ на ваш комментарий. Я хочу применить это к общему представлению на основе класса.   -  person David Simic    schedule 04.01.2015


Ответы (1)


Я обнаружил, что документация Django, касающаяся загрузки файлов, может быть немного сложной для понимания новыми пользователями Django. Тем не менее, я думаю, что следующая ссылка обеспечивает очень краткий и простой пошаговый процесс настройки формы загрузки файлов.

Нужен минимальный пример загрузки файла Django

Я верю, что вы найдете там все, что вам нужно.

Редактировать

В ответ на редактирование и комментарий OP относительно представлений на основе классов я считаю, что они могут быть более четкими и, возможно, «чище» выглядящими кодами, чем представления на основе функций. Вот отличная ссылка, обсуждающая CBV и FBV, которая включает простой, но эффективный пример CBV.

http://www.datalifebalance.com/2014/04/django-file-uploads-with-class-based-views.html

Дополнение к редактированию

Для полноты и для ограничения зависимости ответа от приведенной выше внешней ссылки (которая может однажды исчезнуть) мы добавим еще несколько деталей. Чтобы достичь своей цели, OP может переопределить метод публикации DeckCreateView и сохранить __init__ DeckCreateForm следующим образом:

просмотров.py:

...

class DeckCreateView(CreateView):
    ...
    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect(self.success_url)
        else:
            return render(request, self.template_name, {'form': form})

формы.py

...

class DeckCreateForm(forms.ModelForm):
    ...
    def __init__(self, post_data, files_data):
        self.csv_file = files_data.get('csv_file', None)
        return super(DeckCreateForm, self).__init__(post_data, files_data)

    def save(self, *args, **kwargs):
        deck = super(DeckCreateForm, self).save(*args, **kwargs)
        self.handle_csv_file(self.csv_file, deck)
        return deck

    def handle_csv_file(f, deck):
        ...
        for chunk in f.chunks():
            ... 
        ...

При отправке формы отправляется запрос в DeckCreateView::post. Обработка файла происходит при вызове DeckCreateForm::save.

person alacy    schedule 04.01.2015
comment
Aus_lacy - спасибо, это почти все, что мне нужно. Можете ли вы кратко прокомментировать, как изменить этот пример для работы с представлением создания на основе классов (см. редактирование моего вопроса)? - person David Simic; 04.01.2015