Djeneric Views (Django)
URLconf
from django.conf.urls.defaults import *
from django_website.apps.blog.models import Entry
info_dict = {
'queryset': Entry.objects.all(),
'date_field': 'pub_date',
}
urlpatterns = patterns('django.views.generic.date_based',
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
(r'^(?P<year>\d{4})/$', 'archive_year', info_dict),
(r'^/?$', 'archive_index', info_dict),
)
Simple
direct_to_template
urlpatterns = patterns('django.views.generic.simple',
(r'^foo/$', 'direct_to_template', {'template': 'foo_index.html'}),
(r'^foo/(?P<id>\d+)/$', 'direct_to_template', {'template': 'foo_detail.html'}),
)
redirect_to
urlpatterns = patterns('django.views.generic.simple',
('^foo/(?p<id>\d+)/$', 'redirect_to', {'url': '/bar/%(id)s/'}),
('^bar/$', 'redirect_to', {'url': None}),
)
Complex
list_detail.object_list. (_list.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
author_list_info = {
'queryset' : Author.objects.all(),
'allow_empty': True,
}
urlpatterns = patterns('',
(r'authors/$', list_detail.object_list, author_list_info),
)
reqargs
queryset
optargs
paginate_by
commonargs (7)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
object_list
is_paginated
using page string paramater (GET), or page variable (URLconf)
author_detail_info = {
"queryset" : Author.objects.all(),
"template_object_name" : "author",
}
urlpatterns = patterns('',
(r'^objects/page(?P<page>[0-9]+)/$', 'object_list', dict(info_dict)),
)
/objects/?page=3
results_per_page
has_next
has_previous
page
next
previous
pages
hits
list_detail.object_detail. (_detail.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
author_detail_info = {
"queryset" : Author.objects.all(),
"template_object_name" : "author",
}
urlpatterns = patterns('',
(r'^authors/(?P<object_id>\d+)/$', list_detail.object_detail, author_detail_info),
)
reqargs
queryset
or
object_id
slug + slug_field
optargs
template_name_field
fieldname whose value names the template to use, i.e., 'the_template' --> 'foo.html' --> generic view using foo.html.
commonargs (6)
allow_empty (?)
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
'object'
default name = 'object', e.g., override with template_object_name = 'foo', then object name will be 'foo'.
date_based.
archive_index (_archive.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^books/$', date_based.archive_index, book_info),
)
reqargs
queryset
date_field
optargs
allow_future
default = False
(allows publication of post-dated objects)
num_latest
default = 15
commonargs (6)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name (?)
context
date_list (list of datetime.date objects)
latest
archive_year (_archive_year.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^books/(?P<year>\d{4})/?$', date_based.archive_year, book_info),
)
reqargs
queryset
date_field
year
optargs
allow_future
default = False
(allows publication of post-dated objects)
make_object_list
default = False
(whether to retrieve full year list of objects)
commonargs (7)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
date_list (list of datetime.date objects)
year
object_list
archive_month (_archive_month.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', date_based.archive_month, book_info),
)
reqargs
queryset
date_field
year
month
optargs
allow_future
default = False
(allows publication of post-dated objects)
month_format
default = "%b", e.g., "jan", "feb", etc. re: time.strftime.
"%m" is numbers.
commonargs (7)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
month (datetime.date object)
next_month
previous_month
object_list
archive_week. (_archive_week.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^(?P<year>\d{4})/(?P<week>\d{2})/$', date_based.archive_week, book_info),
)
reqargs
queryset
date_field
year
week
optargs
allow_future
default = False
(allows publication of post-dated objects)
commonargs (7)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
week (datetime.date object)
object_list
archive_day. (_archive_day.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{2})/$', date_based.archive_day, book_info),
)
reqargs
queryset
date_field
year
month
day
optargs
month_format
day_format
default = "%d" (decimal 01-31)
allow_future
commonargs (7)
allow_empty
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
object_list
day
next_day
previous_day
archive_today. (_archive_today.html)
as archive_day.
object_detail (_detail.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\d{2})/(?P<object_id>[\w-]+)/$', date_based.object_detail, book_info),
)
reqargs
queryset
date_field
year
month
day
or
object_id
slug + slug_field
optargs
allow_future
default = False
(allows publication of post-dated objects)
day_format
month_format
template_name_field
commonargs (6)
allow_empty (?)
context_processors
extra_context
mimetype
template_loader
template_name
template_object_name
context
week
(datetime.date object)
object
(w/r/t template_object_name parameter)
create_update. (CRUD CReate/Update/Delete)
"very rough idea of security"
Note that these views all have a very rough idea of security. Although they take a login_required attribute which if given will restrict access to logged-in users, that’s as far as it goes. They won’t, for example, check that the user editing an object is the same user that created it, nor will they validate any sort of permissions.
Much of the time, however, those features can be accomplished by writing a small wrapper around the generic view; see “extending generic views”, below, for more about this topic.
create_object (_form.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^books/create/$', create_update.create_object, {'model' : Book}),
)
reqargs
model
optargs
post_save_redirect
default = object.get_absolute_url()
• post_save_redirect may contain dictionary string formatting, which will be interpolated against the object's field attributes. For example, you could use post_save_redirect="/polls/%(slug)s/".
login_required
default = False
commonargs (4)
allow_empty (?)
context_processors
extra_context
mimetype (?)
template_loader
template_name
template_object_name (?)
context
form (FormWrapper instance)
FormWrapper example
<form action="" method="post">
<p><label for="id_name">Name:</label> {{ form.name }}</p>
<p><label for="id_address">Address:</label> {{ form.address }}</p>
</form>
update_object (_form.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^books/edit/(?P<object_id>\d+)/$', create_update.update_object, {'model' : Book}),
)
reqargs
model
or
object_id
slug + slug_field
optargs
post_save_redirect
default = object.get_absolute_url()
• post_save_redirect may contain dictionary string formatting, which will be interpolated against the object's field attributes. For example, you could use post_save_redirect="/polls/%(slug)s/".
login_required
default = False
commonargs (5)
allow_empty (?)
context_processors
extra_context
mimetype (?)
template_loader
template_name
template_object_name
context
form
(FormWrapper instance)
<form action="" method="post">
<p><label for="id_name">Name:</label> {{ form.name }}</p>
<p><label for="id_address">Address:</label> {{ form.address }}</p>
</form>
object
w/r/t template_object_name
delete_object (_confirm_delete.html)
URLconf example
from django.conf.urls.defaults import *
from django.views.generic import list_detail, date_based, create_update
from bookstore.models import Publisher, Author, Book
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
}
urlpatterns = patterns('',
(r'^books/edit/(?P<object_id>\d+)/$', create_update.update_object, {'model' : Book}),
)
If this view is fetched with GET, it will display a confirmation page (i.e. “do you really want to delete this object?”).
If the view is submitted with POST, the object will be deleted without confirmation.
reqargs
model
or
object_id
slug + slug_field
optargs
post_save_redirect
default = object.get_absolute_url()
• post_save_redirect may contain dictionary string formatting, which will be interpolated against the object's field attributes. For example, you could use post_save_redirect="/polls/%(slug)s/".
login_required
default = False
commonargs (5)
allow_empty (?)
context_processors
extra_context
mimetype (?)
template_loader
template_name
template_object_name
context
form
(FormWrapper instance)
<form action="" method="post">
<p><label for="id_name">Name:</label> {{ form.name }}</p>
<p><label for="id_address">Address:</label> {{ form.address }}</p>
</form>
object
w/r/t template_object_name
Common Arguments (Optional)
allow_empty
else 404
context_processors (template)
list
extra_context
any callable called just before render.
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
"extra_context" : {
"publisher_list" : Publisher.objects.all(),
}
}
mimetype
used for resulting document
template_loader
template_name
override queryset default = <app_label>/<model_name>_list.html, e.g., bookstore/author_list.html
template_object_name
override 'object'/'object_list'.
Extending views
Add extra_context
book_info = {
"queryset" : Book.objects.all(),
"date_field" : "publication_date",
"extra_context" : {
"publisher_list" : Publisher.objects.all(),
}
}
Wrap view function to filter
This works because there’s really nothing special about generic views — they’re just Python functions. Like any view function, generic views expect a certain set of arguments and return HttpResponse objects. Thus, it’s incredibly easy to wrap a small function around a generic view that does additional work before — or after; see below — handing things off to the generic view.
from bookstore.views import browse_alphabetically
urlpatterns = patterns('',
# ...
(r'^books/by-title/([a-z])/$', browse_alphabetically)
)
from bookstore.models import Book
from django.views.generic import list_detail
def browse_alphabetically(request, letter):
return list_detail.object_list(
request,
queryset = Book.objects.filter(title__startswith=letter),
template_name = "bookstore/browse_alphabetically.html",
extra_context = {
'letter' : letter,
}
)
Wrap view function to update field
add the last_accessed field to your Author model
from bookstore.views import author_detail
urlpatterns = patterns('',
#...
(r'^authors/(?P<author_id>d+)/$', author_detail),
)
import datetime
from bookstore.models import Author
from django.views.generic import list_detail
from django.shortcuts import get_object_or_404
def author_detail(request, author_id):
# Look up the Author (and raise a 404 if she's not found)
author = get_object_or_404(Author, pk=author_id)
# Record the last accessed date
author.last_accessed = datetime.datetime.now()
author.save()
# Show the detail page
return list_detail.object_detail(
request,
queryset = Author.objects.all(),
object_id = author_id,
)
Wrap view function for plain text
def author_list_plaintext(request):
response = list_detail.object_list(
queryset = Author.objects.all(),
mimetype = "text/plain",
template_name = "bookstore/author_list.txt"
)
response["Content-Disposition"] = "attachment; filename=authors.txt"
return response