magic-removal: Got generic views working. Their info_dicts now take 'model' instead of 'app_label' and 'module_name'. Updated docs.
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1933 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
0e66c7adec
commit
6fb7423bb0
|
@ -1,4 +1,3 @@
|
|||
from django import models
|
||||
from django.core.xheaders import populate_xheaders
|
||||
from django.core.template import loader
|
||||
from django.core import formfields, meta
|
||||
|
@ -8,13 +7,13 @@ from django.core.paginator import ObjectPaginator, InvalidPage
|
|||
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
||||
from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
|
||||
|
||||
def create_object(request, app_label, module_name, template_name=None,
|
||||
def create_object(request, model, template_name=None,
|
||||
template_loader=loader, extra_context={}, post_save_redirect=None,
|
||||
login_required=False, follow=None, context_processors=None):
|
||||
"""
|
||||
Generic object-creation function.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_form``
|
||||
Templates: ``<app_label>/<model_name>_form``
|
||||
Context:
|
||||
form
|
||||
the form wrapper for the object
|
||||
|
@ -22,13 +21,12 @@ def create_object(request, app_label, module_name, template_name=None,
|
|||
if login_required and request.user.is_anonymous():
|
||||
return redirect_to_login(request.path)
|
||||
|
||||
mod = models.get_module(app_label, module_name)
|
||||
manipulator = mod.AddManipulator(follow=follow)
|
||||
manipulator = model.AddManipulator(follow=follow)
|
||||
if request.POST:
|
||||
# If data was POSTed, we're trying to create a new object
|
||||
new_data = request.POST.copy()
|
||||
|
||||
if mod.Klass._meta.has_field_type(meta.FileField):
|
||||
if model._meta.has_field_type(meta.FileField):
|
||||
new_data.update(request.FILES)
|
||||
|
||||
# Check for errors
|
||||
|
@ -40,7 +38,7 @@ def create_object(request, app_label, module_name, template_name=None,
|
|||
new_object = manipulator.save(new_data)
|
||||
|
||||
if not request.user.is_anonymous():
|
||||
request.user.add_message("The %s was created sucessfully." % mod.Klass._meta.verbose_name)
|
||||
request.user.add_message("The %s was created sucessfully." % model._meta.verbose_name)
|
||||
|
||||
# Redirect to the new object: first by trying post_save_redirect,
|
||||
# then by obj.get_absolute_url; fail if neither works.
|
||||
|
@ -58,7 +56,7 @@ def create_object(request, app_label, module_name, template_name=None,
|
|||
# Create the FormWrapper, template, context, response
|
||||
form = formfields.FormWrapper(manipulator, new_data, errors)
|
||||
if not template_name:
|
||||
template_name = "%s/%s_form" % (app_label, module_name)
|
||||
template_name = "%s/%s_form" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'form': form,
|
||||
|
@ -70,14 +68,14 @@ def create_object(request, app_label, module_name, template_name=None,
|
|||
c[key] = value
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def update_object(request, app_label, module_name, object_id=None, slug=None,
|
||||
def update_object(request, model, object_id=None, slug=None,
|
||||
slug_field=None, template_name=None, template_loader=loader,
|
||||
extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None,
|
||||
login_required=False, follow=None, context_processors=None):
|
||||
"""
|
||||
Generic object-update function.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_form``
|
||||
Templates: ``<app_label>/<model_name>_form``
|
||||
Context:
|
||||
form
|
||||
the form wrapper for the object
|
||||
|
@ -87,23 +85,21 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
|||
if login_required and request.user.is_anonymous():
|
||||
return redirect_to_login(request.path)
|
||||
|
||||
mod = models.get_module(app_label, module_name)
|
||||
|
||||
# Look up the object to be edited
|
||||
lookup_kwargs = {}
|
||||
if object_id:
|
||||
lookup_kwargs['%s__exact' % mod.Klass._meta.pk.name] = object_id
|
||||
lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
|
||||
elif slug and slug_field:
|
||||
lookup_kwargs['%s__exact' % slug_field] = slug
|
||||
else:
|
||||
raise AttributeError("Generic edit view must be called with either an object_id or a slug/slug_field")
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
try:
|
||||
object = mod.get_object(**lookup_kwargs)
|
||||
object = model._default_manager.get_object(**lookup_kwargs)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
|
||||
raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs)
|
||||
|
||||
manipulator = mod.ChangeManipulator(object.id, follow=follow)
|
||||
manipulator = model.ChangeManipulator(object.id, follow=follow)
|
||||
|
||||
if request.POST:
|
||||
new_data = request.POST.copy()
|
||||
|
@ -113,7 +109,7 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
|||
manipulator.save(new_data)
|
||||
|
||||
if not request.user.is_anonymous():
|
||||
request.user.add_message("The %s was updated sucessfully." % mod.Klass._meta.verbose_name)
|
||||
request.user.add_message("The %s was updated sucessfully." % model._meta.verbose_name)
|
||||
|
||||
# Do a post-after-redirect so that reload works, etc.
|
||||
if post_save_redirect:
|
||||
|
@ -129,7 +125,7 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
|||
|
||||
form = formfields.FormWrapper(manipulator, new_data, errors)
|
||||
if not template_name:
|
||||
template_name = "%s/%s_form" % (app_label, module_name)
|
||||
template_name = "%s/%s_form" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'form': form,
|
||||
|
@ -141,10 +137,10 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
|||
else:
|
||||
c[key] = value
|
||||
response = HttpResponse(t.render(c))
|
||||
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
||||
populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
|
||||
return response
|
||||
|
||||
def delete_object(request, app_label, module_name, post_delete_redirect,
|
||||
def delete_object(request, model, post_delete_redirect,
|
||||
object_id=None, slug=None, slug_field=None, template_name=None,
|
||||
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||
login_required=False, context_processors=None):
|
||||
|
@ -155,7 +151,7 @@ def delete_object(request, app_label, module_name, post_delete_redirect,
|
|||
fetched using GET; for safty, deletion will only be performed if this
|
||||
view is POSTed.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_confirm_delete``
|
||||
Templates: ``<app_label>/<model_name>_confirm_delete``
|
||||
Context:
|
||||
object
|
||||
the original object being deleted
|
||||
|
@ -163,30 +159,28 @@ def delete_object(request, app_label, module_name, post_delete_redirect,
|
|||
if login_required and request.user.is_anonymous():
|
||||
return redirect_to_login(request.path)
|
||||
|
||||
mod = models.get_module(app_label, module_name)
|
||||
|
||||
# Look up the object to be edited
|
||||
lookup_kwargs = {}
|
||||
if object_id:
|
||||
lookup_kwargs['%s__exact' % mod.Klass._meta.pk.name] = object_id
|
||||
lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
|
||||
elif slug and slug_field:
|
||||
lookup_kwargs['%s__exact' % slug_field] = slug
|
||||
else:
|
||||
raise AttributeError("Generic delete view must be called with either an object_id or a slug/slug_field")
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
try:
|
||||
object = mod.get_object(**lookup_kwargs)
|
||||
object = model._default_manager.get_object(**lookup_kwargs)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
|
||||
raise Http404, "No %s found for %s" % (model._meta.app_label, lookup_kwargs)
|
||||
|
||||
if request.META['REQUEST_METHOD'] == 'POST':
|
||||
object.delete()
|
||||
if not request.user.is_anonymous():
|
||||
request.user.add_message("The %s was deleted." % mod.Klass._meta.verbose_name)
|
||||
request.user.add_message("The %s was deleted." % model._meta.verbose_name)
|
||||
return HttpResponseRedirect(post_delete_redirect)
|
||||
else:
|
||||
if not template_name:
|
||||
template_name = "%s/%s_confirm_delete" % (app_label, module_name)
|
||||
template_name = "%s/%s_confirm_delete" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'object': object,
|
||||
|
@ -197,5 +191,5 @@ def delete_object(request, app_label, module_name, post_delete_redirect,
|
|||
else:
|
||||
c[key] = value
|
||||
response = HttpResponse(t.render(c))
|
||||
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
||||
populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
|
||||
return response
|
||||
|
|
|
@ -2,41 +2,39 @@ from django.core.template import loader
|
|||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.extensions import DjangoContext
|
||||
from django.core.xheaders import populate_xheaders
|
||||
from django.models import get_module
|
||||
from django.http import Http404, HttpResponse
|
||||
import datetime, time
|
||||
|
||||
def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
||||
def archive_index(request, model, date_field, num_latest=15,
|
||||
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||
extra_context={}, allow_empty=False, context_processors=None):
|
||||
"""
|
||||
Generic top-level archive of date-based objects.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_archive``
|
||||
Templates: ``<app_label>/<model_name>_archive``
|
||||
Context:
|
||||
date_list
|
||||
List of years
|
||||
latest
|
||||
Latest N (defaults to 15) objects by date
|
||||
"""
|
||||
mod = get_module(app_label, module_name)
|
||||
lookup_kwargs = {'%s__lte' % date_field: datetime.datetime.now()}
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
date_list = getattr(mod, "get_%s_list" % date_field)('year', **lookup_kwargs)[::-1]
|
||||
date_list = getattr(model._default_manager, "get_%s_list" % date_field)('year', **lookup_kwargs)[::-1]
|
||||
if not date_list and not allow_empty:
|
||||
raise Http404("No %s.%s available" % (app_label, module_name))
|
||||
raise Http404, "No %s available" % model._meta.verbose_name
|
||||
|
||||
if date_list and num_latest:
|
||||
lookup_kwargs.update({
|
||||
'limit': num_latest,
|
||||
'order_by': ('-' + date_field,),
|
||||
})
|
||||
latest = mod.get_list(**lookup_kwargs)
|
||||
latest = model._default_manager.get_list(**lookup_kwargs)
|
||||
else:
|
||||
latest = None
|
||||
|
||||
if not template_name:
|
||||
template_name = "%s/%s_archive" % (app_label, module_name)
|
||||
template_name = "%s/%s_archive" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'date_list' : date_list,
|
||||
|
@ -49,31 +47,30 @@ def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
|||
c[key] = value
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def archive_year(request, year, app_label, module_name, date_field,
|
||||
def archive_year(request, year, model, date_field,
|
||||
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||
extra_context={}, context_processors=None):
|
||||
"""
|
||||
Generic yearly archive view.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_archive_year``
|
||||
Templates: ``<app_label>/<model_name>_archive_year``
|
||||
Context:
|
||||
date_list
|
||||
List of months in this year with objects
|
||||
year
|
||||
This year
|
||||
"""
|
||||
mod = get_module(app_label, module_name)
|
||||
now = datetime.datetime.now()
|
||||
lookup_kwargs = {'%s__year' % date_field: year}
|
||||
# Only bother to check current date if the year isn't in the past.
|
||||
if int(year) >= now.year:
|
||||
lookup_kwargs['%s__lte' % date_field] = now
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
date_list = getattr(mod, "get_%s_list" % date_field)('month', **lookup_kwargs)
|
||||
date_list = getattr(model._default_manager, "get_%s_list" % date_field)('month', **lookup_kwargs)
|
||||
if not date_list:
|
||||
raise Http404
|
||||
if not template_name:
|
||||
template_name = "%s/%s_archive_year" % (app_label, module_name)
|
||||
template_name = "%s/%s_archive_year" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'date_list': date_list,
|
||||
|
@ -86,13 +83,13 @@ def archive_year(request, year, app_label, module_name, date_field,
|
|||
c[key] = value
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def archive_month(request, year, month, app_label, module_name, date_field,
|
||||
def archive_month(request, year, month, model, date_field,
|
||||
month_format='%b', template_name=None, template_loader=loader,
|
||||
extra_lookup_kwargs={}, extra_context={}, context_processors=None):
|
||||
"""
|
||||
Generic monthly archive view.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_archive_month``
|
||||
Templates: ``<app_label>/<model_name>_archive_month``
|
||||
Context:
|
||||
month:
|
||||
this month
|
||||
|
@ -104,7 +101,6 @@ def archive_month(request, year, month, app_label, module_name, date_field,
|
|||
except ValueError:
|
||||
raise Http404
|
||||
|
||||
mod = get_module(app_label, module_name)
|
||||
now = datetime.datetime.now()
|
||||
# Calculate first and last day of month, for use in a date-range lookup.
|
||||
first_day = date.replace(day=1)
|
||||
|
@ -117,11 +113,11 @@ def archive_month(request, year, month, app_label, module_name, date_field,
|
|||
if last_day >= now.date():
|
||||
lookup_kwargs['%s__lte' % date_field] = now
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
object_list = mod.get_list(**lookup_kwargs)
|
||||
object_list = model._default_manager.get_list(**lookup_kwargs)
|
||||
if not object_list:
|
||||
raise Http404
|
||||
if not template_name:
|
||||
template_name = "%s/%s_archive_month" % (app_label, module_name)
|
||||
template_name = "%s/%s_archive_month" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'object_list': object_list,
|
||||
|
@ -134,14 +130,14 @@ def archive_month(request, year, month, app_label, module_name, date_field,
|
|||
c[key] = value
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def archive_day(request, year, month, day, app_label, module_name, date_field,
|
||||
def archive_day(request, year, month, day, model, date_field,
|
||||
month_format='%b', day_format='%d', template_name=None,
|
||||
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||
allow_empty=False, context_processors=None):
|
||||
"""
|
||||
Generic daily archive view.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_archive_day``
|
||||
Templates: ``<app_label>/<model_name>_archive_day``
|
||||
Context:
|
||||
object_list:
|
||||
list of objects published that day
|
||||
|
@ -157,7 +153,6 @@ def archive_day(request, year, month, day, app_label, module_name, date_field,
|
|||
except ValueError:
|
||||
raise Http404
|
||||
|
||||
mod = get_module(app_label, module_name)
|
||||
now = datetime.datetime.now()
|
||||
lookup_kwargs = {
|
||||
'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
|
||||
|
@ -166,11 +161,11 @@ def archive_day(request, year, month, day, app_label, module_name, date_field,
|
|||
if date >= now.date():
|
||||
lookup_kwargs['%s__lte' % date_field] = now
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
object_list = mod.get_list(**lookup_kwargs)
|
||||
object_list = model._default_manager.get_list(**lookup_kwargs)
|
||||
if not allow_empty and not object_list:
|
||||
raise Http404
|
||||
if not template_name:
|
||||
template_name = "%s/%s_archive_day" % (app_label, module_name)
|
||||
template_name = "%s/%s_archive_day" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
c = DjangoContext(request, {
|
||||
'object_list': object_list,
|
||||
|
@ -197,7 +192,7 @@ def archive_today(request, **kwargs):
|
|||
})
|
||||
return archive_day(request, **kwargs)
|
||||
|
||||
def object_detail(request, year, month, day, app_label, module_name, date_field,
|
||||
def object_detail(request, year, month, day, model, date_field,
|
||||
month_format='%b', day_format='%d', object_id=None, slug=None,
|
||||
slug_field=None, template_name=None, template_name_field=None,
|
||||
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||
|
@ -205,7 +200,7 @@ def object_detail(request, year, month, day, app_label, module_name, date_field,
|
|||
"""
|
||||
Generic detail view from year/month/day/slug or year/month/day/id structure.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_detail``
|
||||
Templates: ``<app_label>/<model_name>_detail``
|
||||
Context:
|
||||
object:
|
||||
the object to be detailed
|
||||
|
@ -215,7 +210,6 @@ def object_detail(request, year, month, day, app_label, module_name, date_field,
|
|||
except ValueError:
|
||||
raise Http404
|
||||
|
||||
mod = get_module(app_label, module_name)
|
||||
now = datetime.datetime.now()
|
||||
lookup_kwargs = {
|
||||
'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
|
||||
|
@ -224,18 +218,18 @@ def object_detail(request, year, month, day, app_label, module_name, date_field,
|
|||
if date >= now.date():
|
||||
lookup_kwargs['%s__lte' % date_field] = now
|
||||
if object_id:
|
||||
lookup_kwargs['%s__exact' % mod.Klass._meta.pk.name] = object_id
|
||||
lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id
|
||||
elif slug and slug_field:
|
||||
lookup_kwargs['%s__exact' % slug_field] = slug
|
||||
else:
|
||||
raise AttributeError("Generic detail view must be called with either an object_id or a slug/slugfield")
|
||||
raise AttributeError, "Generic detail view must be called with either an object_id or a slug/slugfield"
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
try:
|
||||
object = mod.get_object(**lookup_kwargs)
|
||||
object = model._default_manager.get_object(**lookup_kwargs)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
|
||||
raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs)
|
||||
if not template_name:
|
||||
template_name = "%s/%s_detail" % (app_label, module_name)
|
||||
template_name = "%s/%s_detail" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
if template_name_field:
|
||||
template_name_list = [getattr(object, template_name_field), template_name]
|
||||
t = template_loader.select_template(template_name_list)
|
||||
|
@ -250,5 +244,5 @@ def object_detail(request, year, month, day, app_label, module_name, date_field,
|
|||
else:
|
||||
c[key] = value
|
||||
response = HttpResponse(t.render(c))
|
||||
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
||||
populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
|
||||
return response
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from django import models
|
||||
from django.core.template import loader
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.core.xheaders import populate_xheaders
|
||||
|
@ -6,13 +5,13 @@ from django.core.extensions import DjangoContext
|
|||
from django.core.paginator import ObjectPaginator, InvalidPage
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
def object_list(request, app_label, module_name, paginate_by=None, allow_empty=False,
|
||||
def object_list(request, model, paginate_by=None, allow_empty=False,
|
||||
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||
extra_context={}, context_processors=None):
|
||||
"""
|
||||
Generic list of objects.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_list``
|
||||
Templates: ``<app_label>/<model_name>_list``
|
||||
Context:
|
||||
object_list
|
||||
list of objects
|
||||
|
@ -35,10 +34,9 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
|||
hits
|
||||
number of objects, total
|
||||
"""
|
||||
mod = models.get_module(app_label, module_name)
|
||||
lookup_kwargs = extra_lookup_kwargs.copy()
|
||||
if paginate_by:
|
||||
paginator = ObjectPaginator(mod, lookup_kwargs, paginate_by)
|
||||
paginator = ObjectPaginator(model, lookup_kwargs, paginate_by)
|
||||
page = request.GET.get('page', 0)
|
||||
try:
|
||||
object_list = paginator.get_page(page)
|
||||
|
@ -61,7 +59,7 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
|||
'hits' : paginator.hits,
|
||||
}, context_processors)
|
||||
else:
|
||||
object_list = mod.get_list(**lookup_kwargs)
|
||||
object_list = model._default_manager.get_list(**lookup_kwargs)
|
||||
c = DjangoContext(request, {
|
||||
'object_list': object_list,
|
||||
'is_paginated': False
|
||||
|
@ -74,37 +72,36 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
|||
else:
|
||||
c[key] = value
|
||||
if not template_name:
|
||||
template_name = "%s/%s_list" % (app_label, module_name)
|
||||
template_name = "%s/%s_list" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
t = template_loader.get_template(template_name)
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def object_detail(request, app_label, module_name, object_id=None, slug=None,
|
||||
def object_detail(request, model, object_id=None, slug=None,
|
||||
slug_field=None, template_name=None, template_name_field=None,
|
||||
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||
context_processors=None):
|
||||
"""
|
||||
Generic list of objects.
|
||||
|
||||
Templates: ``<app_label>/<module_name>_detail``
|
||||
Templates: ``<app_label>/<model_name>_detail``
|
||||
Context:
|
||||
object
|
||||
the object
|
||||
"""
|
||||
mod = models.get_module(app_label, module_name)
|
||||
lookup_kwargs = {}
|
||||
if object_id:
|
||||
lookup_kwargs['pk'] = object_id
|
||||
elif slug and slug_field:
|
||||
lookup_kwargs['%s__exact' % slug_field] = slug
|
||||
else:
|
||||
raise AttributeError("Generic detail view must be called with either an object_id or a slug/slug_field")
|
||||
raise AttributeError, "Generic detail view must be called with either an object_id or a slug/slug_field."
|
||||
lookup_kwargs.update(extra_lookup_kwargs)
|
||||
try:
|
||||
object = mod.get_object(**lookup_kwargs)
|
||||
object = model._default_manager.get_object(**lookup_kwargs)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
|
||||
raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs)
|
||||
if not template_name:
|
||||
template_name = "%s/%s_detail" % (app_label, module_name)
|
||||
template_name = "%s/%s_detail" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
if template_name_field:
|
||||
template_name_list = [getattr(object, template_name_field), template_name]
|
||||
t = template_loader.select_template(template_name_list)
|
||||
|
@ -119,5 +116,5 @@ def object_detail(request, app_label, module_name, object_id=None, slug=None,
|
|||
else:
|
||||
c[key] = value
|
||||
response = HttpResponse(t.render(c))
|
||||
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
||||
populate_xheaders(request, response, model, getattr(object, object._meta.pk.name))
|
||||
return response
|
||||
|
|
|
@ -5,7 +5,7 @@ Using generic views
|
|||
Writing Web applications can be monotonous, because we repeat certain patterns
|
||||
again and again. In Django, the most common of these patterns have been
|
||||
abstracted into "generic views" that let you quickly provide common views of
|
||||
an object without actually needing to write any views.
|
||||
an object without actually needing to write any Python code.
|
||||
|
||||
Django's generic views contain the following:
|
||||
|
||||
|
@ -32,10 +32,10 @@ URLconf tuple. For example, here's the URLconf for the simple weblog app that
|
|||
drives the blog on djangoproject.com::
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
from django_website.apps.blog.models import Entry
|
||||
|
||||
info_dict = {
|
||||
'app_label': 'blog',
|
||||
'module_name': 'entries',
|
||||
'model': Entry,
|
||||
'date_field': 'pub_date',
|
||||
}
|
||||
|
||||
|
@ -47,26 +47,18 @@ drives the blog on djangoproject.com::
|
|||
(r'^/?$', 'archive_index', info_dict),
|
||||
)
|
||||
|
||||
As you can see, this URLconf defines a few options in ``info_dict`` that tell
|
||||
the generic view which model to use (``blog.entries`` in this case), as well as
|
||||
As you can see, this URLconf defines a few options in ``info_dict``. ``'model'``
|
||||
tells the generic view which model to use (``Entry``, in this case), as well as
|
||||
some extra information.
|
||||
|
||||
Documentation of each generic view follows, along with a list of all keyword
|
||||
arguments that a generic view expects. Remember that as in the example above,
|
||||
arguments may either come from the URL pattern (as ``month``, ``day``,
|
||||
``year``, etc. do above) or from the additional-information dictionary (as for
|
||||
``app_label``, ``module_name``, etc.).
|
||||
``model``, ``date_field``, etc.).
|
||||
|
||||
Most of the generic views that follow require the ``app_label`` and
|
||||
``module_name`` keys. These values are easiest to explain through example::
|
||||
|
||||
>>> from django.models.blog import entries
|
||||
|
||||
In the above line, ``blog`` is the ``app_label`` (the name of the file that
|
||||
holds all your model definitions) and ``entries`` is the ``module_name``
|
||||
(either a pluralized, lowercased version of the model class name, or the value
|
||||
of the ``module_name`` option of your model). In the docs below, these keys
|
||||
will not be repeated, but each generic view requires them.
|
||||
Most generic views require the ``model`` key, which is your model class (*not*
|
||||
an instance of the class).
|
||||
|
||||
Using "simple" generic views
|
||||
============================
|
||||
|
@ -109,10 +101,9 @@ Using date-based generic views
|
|||
==============================
|
||||
|
||||
Date-based generic views (in the module ``django.views.generic.date_based``)
|
||||
feature six functions for dealing with date-based data. Besides ``app_label``
|
||||
and ``module_name``, all date-based generic views require that the
|
||||
``date_field`` argument be passed to them. This is the name of the field that
|
||||
stores the date the objects should key off of.
|
||||
feature six functions for dealing with date-based data. Besides ``model``, all
|
||||
date-based generic views require the ``date_field`` argument. This is the name
|
||||
of the field that stores the date the objects should key off of.
|
||||
|
||||
Additionally, all date-based generic views have the following optional
|
||||
arguments:
|
||||
|
@ -155,7 +146,14 @@ The date-based generic functions are:
|
|||
an empty index page. ``False`` is default.
|
||||
======================= =================================================
|
||||
|
||||
Uses the template ``app_label/module_name_archive`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_archive`` by default, where:
|
||||
|
||||
* ``<model_name>`` is your model's name in all lowercase. For a model
|
||||
``StaffMember``, that'd be ``staffmember``.
|
||||
|
||||
* ``<app_label>`` is the right-most part of the full Python path to
|
||||
your model's app. For example, if your model lives in
|
||||
``apps/blog/models.py``, that'd be ``blog``.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -168,7 +166,7 @@ The date-based generic functions are:
|
|||
Yearly archive. Requires that the ``year`` argument be present in the URL
|
||||
pattern.
|
||||
|
||||
Uses the template ``app_label/module_name_archive_year`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_archive_year`` by default.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -187,7 +185,7 @@ The date-based generic functions are:
|
|||
default, which is a three-letter month abbreviation. To change it to use
|
||||
numbers, use ``"%m"``.
|
||||
|
||||
Uses the template ``app_label/module_name_archive_month`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_archive_month`` by default.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -204,7 +202,7 @@ The date-based generic functions are:
|
|||
also pass ``day_format``, which defaults to ``"%d"`` (day of the month as a
|
||||
decimal number, 1-31).
|
||||
|
||||
Uses the template ``app_label/module_name_archive_day`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_archive_day`` by default.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -274,7 +272,7 @@ Individual views are:
|
|||
an empty index page. ``False`` is default.
|
||||
======================= =================================================
|
||||
|
||||
Uses the template ``app_label/module_name_list`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_list`` by default.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -327,7 +325,7 @@ The create/update/delete views are:
|
|||
be interpolated against the object's field attributes. For example, you
|
||||
could use ``post_save_redirect="/polls/%(slug)s/"``.
|
||||
|
||||
Uses the template ``app_label/module_name_form`` by default. This is the
|
||||
Uses the template ``<app_label>/<model_name>_form`` by default. This is the
|
||||
same template as the ``update_object`` view below. Your template can tell
|
||||
the different by the presence or absence of ``{{ object }}`` in the
|
||||
context.
|
||||
|
@ -349,7 +347,7 @@ The create/update/delete views are:
|
|||
``list_detail.object_detail`` does (see above), and the same
|
||||
``post_save_redirect`` as ``create_object`` does.
|
||||
|
||||
Uses the template ``app_label/module_name_form`` by default.
|
||||
Uses the template ``<app_label>/<model_name>_form`` by default.
|
||||
|
||||
Has the following template context:
|
||||
|
||||
|
@ -368,7 +366,7 @@ The create/update/delete views are:
|
|||
that the view knows where to go after the object is deleted.
|
||||
|
||||
If fetched with GET, it uses the template
|
||||
``app_label/module_name_confirm_delete`` by default. It uses no template
|
||||
``<app_label>/<model_name>_confirm_delete`` by default. It uses no template
|
||||
if POSTed -- it simply deletes the object and redirects.
|
||||
|
||||
Has the following template context:
|
||||
|
|
Loading…
Reference in New Issue