Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Django's Generic Views

I'm writing my first app in Django, and I have a problem with the create_object Generic View; In my urls.py, I have:

(r'^new$', CreateView.as_view()),

The problem is that when the user submits the "new" form, I need to manipulate the data that will be saved to the database (I actually need to add the user_id foreign key); without Generic Views I used to write:

    form = ClientForm(request.POST)
    if form.is_valid():
        data = form.save(commit=False)
        data.user = request.user
        data.save()
        form.save_m2m()

in my view (notice data.user=request.user). I've searched Django docs but I can't find a way to do this (maybe by extending the CreateView class) - somewere in The Book there is only an example that overrides the get_object method of a ListView class to update a last_accessed_date field.

like image 890
Simone Lusenti Avatar asked Aug 22 '11 11:08

Simone Lusenti


People also ask

What are generic views?

Django's generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.

Should I use class-based views?

The most significant advantage of the class-based view is inheritance. In the class-based view, you can inherit another class, and it can be modified for the different use cases. It helps you in following the DRY principle. You won't have to write the same code over and over in your boilerplate.

How do you add decorators to class-based view?

To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class. The decorators will process a request in the order they are passed to the decorator.

What is generic list view in Django?

List View refers to a view (logic) to display multiple instances of a table in the database. We have already discussed the basics of List View in List View – Function based Views Django. Class-based views provide an alternative way to implement views as Python objects instead of functions.


1 Answers

You can do this by overriding the get_form method:

from django.views.generic import CreateView

class CustomCreateView(CreateView):
    def get_form(self, form_class):
        form = super(CustomCreateView, self).get_form(form_class)
        form.instance.user = self.request.user
        return form

EDIT: Nowadays I would override form_valid as per Issac Kelly's answer:

from django.views.generic import CreateView

class CustomCreateView(CreateView):
    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(CustomCreateView, self).form_valid(form)
like image 111
meshy Avatar answered Sep 25 '22 10:09

meshy