1

I'm running Django 1.7.

I have the following model form:

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

Notice that the file field is not part of the model (and I would like to keep it this way). This file field is meant to provide an alternative means of constructing the model Deck.

I would like to know how to access the uploaded file. I looked in my media directory but it is not there. I tried adding a "upload_to" to the csv_file constructor but get an error:

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

EDIT:

I would like to know how to get this to work with a generic class based create view which makes use of the above model form - in views.py I have:

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

Specifically, how do I modify something like http://docs.djangoproject.com/en/1.7/topics/http/file-uploads to work with the above class based view. My urls.py file:

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

Is there a method which I can override in DeckCreateView to handle the file upload?

David Simic
  • 2,061
  • 2
  • 19
  • 33
  • 3
    https://docs.djangoproject.com/en/1.7/topics/http/file-uploads/ this explains the process pretty well. – kviktor Jan 03 '15 at 17:21
  • kviktor - I edited the question in response to your comment. I'm looking to apply this to a generic class based view. – David Simic Jan 04 '15 at 15:02

1 Answers1

0

I've found that the Django documentation concerning file uploads can be a little difficult to understand for newer Django users. However, I think that the following link provides a very concise and easy to follow step by step process of setting up a file upload form.

Need a minimal Django file upload example

I believe you'll find everything you need there.

Edit

In response to the OP's edit and comment concerning class based views, I believe they can be clearer and arguably "cleaner" looking code than function based views. Here is a great link discussing CBV and FBV that includes a simple, but effective example of CBV.

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

Addendum to Edit

For the sake of completeness, and to limit the dependence of the answer on the above external link (which may disappear one day), we add a few more details. In order to achieve their objective, the OP could override the post method of DeckCreateView and save, __init__ of DeckCreateForm like so:

views.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})

forms.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():
            ... 
        ...

Upon form submission a request is sent to DeckCreateView::post. The file handling occurs when DeckCreateForm::save is called.

Community
  • 1
  • 1
alacy
  • 4,972
  • 8
  • 30
  • 47
  • Aus_lacy - thanks that is almost everything I need. Can you briefly comment on how to modify that example to work with a classed based create view (see the edit to my question)? – David Simic Jan 04 '15 at 14:52