What you have is a python error -- self
is not defined. self
is generally what refers to the class instance itself on class methods.
Anyways, I agree, it's brand spanking new and not as documented. I think looking at the source is absolutely key at this point.
To get comfortable with class based views, I'd start by subclassing django.views.generic.base.View
, which implements only a few methods, namely attempting to call a function on the class based on the request method (post, get, head, - look at source).
For example, here's the first step to replace view functions with the new view classes:
class MyClassBasedView(View):
def get(self, request):
# behave exactly like old style views
# except this is called only on get request
return http.HttpResponse("Get")
def post(self, request):
return http.HttpResponse("Post")
(r'^foobar/$', MyClassBasedView.as_view())
Back to your specific question:
All TemplateView.as_view()
does is render the template - CreateView
is a combination of several other classes that handle ModelForms
and template rendering (TemplateView
).
So, for a very basic example, look to the docs for what class mixins
are used by CreateView
.
We see it implements TemplateResponseMixin
, ModelFormMixin
, and ProcessFormView
, each containing a list of methods for those classes.
The most basic CreateView
At the most basic level, provide CreateView
's ModelFormMixin
with the model or custom ModelForm class as documented here.
Your CreateView
class would look something like the following
class AuthorCreateView(CreateView):
form_class = AuthorForm
template_name = 'author_new.html'
success_url = 'success'
With those 3 core attributes set, call it in your URLs.
('^authors/create/$', Author.AuthorCreateView.as_view()),
Render the page and you'll see your ModelForm passed to the template as form
, handling the form validation step (passing in request.POST
/ re-render if invalid), as well as calling form.save()
and redirecting to the success_url
.
Start overriding the class methods
To customize behavior, start overriding the methods documented for the mixins
.
Remember that you simply need to return an HttpResponse
from one of these methods just like any regular view function.
Example overriding form_invalid
documented in ModelFormMixin
:
class AuthorCreateView(CreateView):
form_class = AuthorForm
template_name = 'author_new.html'
success_url = 'success'
def form_invalid(self, form):
return http.HttpResponse("form is invalid.. this is just an HttpResponse object")
This per-method overriding starts becoming extremely useful as your forms grow more advanced and ultimately lets you build huge forms with a handful of lines of code, overriding only what is necessary.
Say you want to pass your form custom parameters such as the request
object (very common if you need access to the user in the form): you merely need to override get_form_kwargs
.
class MyFormView(FormView):
def get_form_kwargs(self):
# pass "user" keyword argument with the current user to your form
kwargs = super(MyFormView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
Class based views are a shining example of smart class usage. It gave me a great intro towards building my own mixins for views and python classes in general. It is saving countless hours.
Wow this got long. To think it started as a mere URL to the docs comment :)