Fixed #10030 -- Corrected a typo in a reference to the login_required decorator. Thanks to mk for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9860 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2009-02-22 06:08:13 +00:00
parent b1d487e0f8
commit f1e8d24e0c
1 changed files with 47 additions and 47 deletions

View File

@ -64,9 +64,9 @@ Let's take a look at a very simple example of the ``ModelAdmin``::
from django.contrib import admin from django.contrib import admin
from myproject.myapp.models import Author from myproject.myapp.models import Author
admin.site.register(Author) admin.site.register(Author)
``ModelAdmin`` Options ``ModelAdmin`` Options
---------------------- ----------------------
@ -138,13 +138,13 @@ The ``field_options`` dictionary can have the following keys:
* ``fields`` * ``fields``
A tuple of field names to display in this fieldset. This key is A tuple of field names to display in this fieldset. This key is
required. required.
Example:: Example::
{ {
'fields': ('first_name', 'last_name', 'address', 'city', 'state'), 'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
} }
To display multiple fields on the same line, wrap those fields in To display multiple fields on the same line, wrap those fields in
their own tuple. In this example, the ``first_name`` and ``last_name`` their own tuple. In this example, the ``first_name`` and ``last_name``
fields will display on the same line:: fields will display on the same line::
@ -155,9 +155,9 @@ The ``field_options`` dictionary can have the following keys:
* ``classes`` * ``classes``
A list containing extra CSS classes to apply to the fieldset. A list containing extra CSS classes to apply to the fieldset.
Example:: Example::
{ {
'classes': ['wide', 'extrapretty'], 'classes': ['wide', 'extrapretty'],
} }
@ -213,10 +213,10 @@ For example, let's consider the following model::
If you want a form for the ``Author`` model that includes only the ``name`` If you want a form for the ``Author`` model that includes only the ``name``
and ``title`` fields, you would specify ``fields`` or ``exclude`` like this:: and ``title`` fields, you would specify ``fields`` or ``exclude`` like this::
class AuthorAdmin(admin.ModelAdmin): class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title') fields = ('name', 'title')
class AuthorAdmin(admin.ModelAdmin): class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',) exclude = ('birth_date',)
@ -254,30 +254,30 @@ that displays the ``__unicode__()`` representation of each object.
You have four possible values that can be used in ``list_display``: You have four possible values that can be used in ``list_display``:
* A field of the model. For example:: * A field of the model. For example::
class PersonAdmin(admin.ModelAdmin): class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name') list_display = ('first_name', 'last_name')
* A callable that accepts one parameter for the model instance. For * A callable that accepts one parameter for the model instance. For
example:: example::
def upper_case_name(obj): def upper_case_name(obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper() return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name' upper_case_name.short_description = 'Name'
class PersonAdmin(admin.ModelAdmin): class PersonAdmin(admin.ModelAdmin):
list_display = (upper_case_name,) list_display = (upper_case_name,)
* A string representing an attribute on the ``ModelAdmin``. This behaves * A string representing an attribute on the ``ModelAdmin``. This behaves
same as the callable. For example:: same as the callable. For example::
class PersonAdmin(admin.ModelAdmin): class PersonAdmin(admin.ModelAdmin):
list_display = ('upper_case_name',) list_display = ('upper_case_name',)
def upper_case_name(self, obj): def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper() return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name' upper_case_name.short_description = 'Name'
* A string representing an attribute on the model. This behaves almost * A string representing an attribute on the model. This behaves almost
the same as the callable, but ``self`` in this context is the model the same as the callable, but ``self`` in this context is the model
instance. Here's a full model example:: instance. Here's a full model example::
@ -311,7 +311,7 @@ A few special cases to note about ``list_display``:
callable, Django will HTML-escape the output by default. If you'd rather callable, Django will HTML-escape the output by default. If you'd rather
not escape the output of the method, give the method an ``allow_tags`` not escape the output of the method, give the method an ``allow_tags``
attribute whose value is ``True``. attribute whose value is ``True``.
Here's a full example model:: Here's a full example model::
class Person(models.Model): class Person(models.Model):
@ -613,16 +613,16 @@ do that::
from django.db import models from django.db import models
from django.contrib import admin from django.contrib import admin
# Import our custom widget and our model from where they're defined # Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel from myapp.models import MyModel
class MyModelAdmin(admin.ModelAdmin): class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = { formfield_overrides = {
models.TextField: {'widget': RichTextEditorWidget}, models.TextField: {'widget': RichTextEditorWidget},
} }
Note that the key in the dictionary is the actual field class, *not* a string. Note that the key in the dictionary is the actual field class, *not* a string.
The value is another dictionary; these arguments will be passed to The value is another dictionary; these arguments will be passed to
:meth:`~django.forms.Field.__init__`. See :ref:`ref-forms-api` for details. :meth:`~django.forms.Field.__init__`. See :ref:`ref-forms-api` for details.
@ -676,18 +676,18 @@ model instance::
``get_urls(self)`` ``get_urls(self)``
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for
that ModelAdmin in the same way as a URLconf. Therefore you can extend them as that ModelAdmin in the same way as a URLconf. Therefore you can extend them as
documented in :ref:`topics-http-urls`:: documented in :ref:`topics-http-urls`::
class MyModelAdmin(admin.ModelAdmin): class MyModelAdmin(admin.ModelAdmin):
def get_urls(self): def get_urls(self):
urls = super(MyModelAdmin, self).get_urls() urls = super(MyModelAdmin, self).get_urls()
my_urls = patterns('', my_urls = patterns('',
(r'^my_view/$', self.my_view) (r'^my_view/$', self.my_view)
) )
return my_urls + urls return my_urls + urls
.. note:: .. note::
Notice that the custom patterns are included *before* the regular admin Notice that the custom patterns are included *before* the regular admin
@ -707,13 +707,13 @@ so::
urls = super(MyModelAdmin, self).get_urls() urls = super(MyModelAdmin, self).get_urls()
my_urls = patterns('', my_urls = patterns('',
(r'^my_view/$', self.admin_site.admin_view(self.my_view)) (r'^my_view/$', self.admin_site.admin_view(self.my_view))
) )
return my_urls + urls return my_urls + urls
Notice the wrapped view in the fifth line above:: Notice the wrapped view in the fifth line above::
(r'^my_view/$', self.admin_site.admin_view(self.my_view)) (r'^my_view/$', self.admin_site.admin_view(self.my_view))
This wrapping will protect ``self.my_view`` from unauthorized access. This wrapping will protect ``self.my_view`` from unauthorized access.
``formfield_for_foreignkey(self, db_field, request, **kwargs)`` ``formfield_for_foreignkey(self, db_field, request, **kwargs)``
@ -763,11 +763,11 @@ the ability define your own form::
``MyArticleAdminForm`` can be defined anywhere as long as you import where ``MyArticleAdminForm`` can be defined anywhere as long as you import where
needed. Now within your form you can add your own custom validation for needed. Now within your form you can add your own custom validation for
any field:: any field::
class MyArticleAdminForm(forms.ModelForm): class MyArticleAdminForm(forms.ModelForm):
class Meta: class Meta:
model = Article model = Article
def clean_name(self): def clean_name(self):
# do something that validates your data # do something that validates your data
return self.cleaned_data["name"] return self.cleaned_data["name"]
@ -906,7 +906,7 @@ Working with Many-to-Many Intermediary Models
By default, admin widgets for many-to-many relations will be displayed inline By default, admin widgets for many-to-many relations will be displayed inline
on whichever model contains the actual reference to the ``ManyToManyField``. on whichever model contains the actual reference to the ``ManyToManyField``.
However, when you specify an intermediary model using the ``through`` However, when you specify an intermediary model using the ``through``
argument to a ``ManyToManyField``, the admin will not display a widget by argument to a ``ManyToManyField``, the admin will not display a widget by
default. This is because each instance of that intermediary model requires default. This is because each instance of that intermediary model requires
more information than could be displayed in a single widget, and the layout more information than could be displayed in a single widget, and the layout
required for multiple widgets will vary depending on the intermediate model. required for multiple widgets will vary depending on the intermediate model.
@ -917,7 +917,7 @@ models::
class Person(models.Model): class Person(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
class Group(models.Model): class Group(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership') members = models.ManyToManyField(Person, through='Membership')
@ -948,7 +948,7 @@ Now create admin views for the ``Person`` and ``Group`` models::
inlines = (MembershipInline,) inlines = (MembershipInline,)
Finally, register your ``Person`` and ``Group`` models with the admin site:: Finally, register your ``Person`` and ``Group`` models with the admin site::
admin.site.register(Person, PersonAdmin) admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin) admin.site.register(Group, GroupAdmin)
@ -966,7 +966,7 @@ you have the following models::
content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey("content_type", "object_id") content_object = generic.GenericForeignKey("content_type", "object_id")
class Product(models.Model): class Product(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
@ -977,17 +977,17 @@ example app::
from django.contrib import admin from django.contrib import admin
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from myproject.myapp.models import Image, Product from myproject.myapp.models import Image, Product
class ImageInline(generic.GenericTabularInline): class ImageInline(generic.GenericTabularInline):
model = Image model = Image
class ProductAdmin(admin.ModelAdmin): class ProductAdmin(admin.ModelAdmin):
inlines = [ inlines = [
ImageInline, ImageInline,
] ]
admin.site.register(Product, ProductAdmin) admin.site.register(Product, ProductAdmin)
``django.contrib.contenttypes.generic`` provides both a ``GenericTabularInline`` ``django.contrib.contenttypes.generic`` provides both a ``GenericTabularInline``
@ -1174,8 +1174,8 @@ respectively::
Adding views to admin sites Adding views to admin sites
--------------------------- ---------------------------
It possible to add additional views to the admin site in the same way one can It possible to add additional views to the admin site in the same way one can
add them to ``ModelAdmins``. This by using the ``get_urls()`` method on an add them to ``ModelAdmins``. This by using the ``get_urls()`` method on an
AdminSite in the same way as `described above`__ AdminSite in the same way as `described above`__
__ `get_urls(self)`_ __ `get_urls(self)`_
@ -1183,13 +1183,13 @@ __ `get_urls(self)`_
Protecting Custom ``AdminSite`` and ``ModelAdmin`` Protecting Custom ``AdminSite`` and ``ModelAdmin``
-------------------------------------------------- --------------------------------------------------
By default all the views in the Django admin are protected so that only staff By default all the views in the Django admin are protected so that only staff
members can access them. If you add your own views to either a ``ModelAdmin`` members can access them. If you add your own views to either a ``ModelAdmin``
or ``AdminSite`` you should ensure that where necessary they are protected in or ``AdminSite`` you should ensure that where necessary they are protected in
the same manner. To do this use the ``admin_perm_test`` decorator provided in the same manner. To do this use the ``admin_perm_test`` decorator provided in
``django.contrib.admin.utils.admin_perm_test``. It can be used in the same way ``django.contrib.admin.utils.admin_perm_test``. It can be used in the same way
as the ``login_requied`` decorator. as the ``login_required`` decorator.
.. note:: .. note::
The ``admin_perm_test`` decorator can only be used on methods which are on The ``admin_perm_test`` decorator can only be used on methods which are on
``ModelAdmins`` or ``AdminSites``, you cannot use it on arbitrary functions. ``ModelAdmins`` or ``AdminSites``, you cannot use it on arbitrary functions.