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:
parent
b1d487e0f8
commit
f1e8d24e0c
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue