Improved admin model registration options: you can now register using register(Model, **options) and even register(Model, ModelAdmin, **options). This isn't documented yet -- a much expanded version of docs/admin.txt is on the way.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8063 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2008-07-23 18:58:06 +00:00
parent 508016c0f4
commit 7b3cf13d32
3 changed files with 86 additions and 7 deletions

View File

@ -1,6 +1,7 @@
from django import http, template from django import http, template
from django.contrib.admin import ModelAdmin from django.contrib.admin import ModelAdmin
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from django.core.exceptions import ImproperlyConfigured
from django.db.models.base import ModelBase from django.db.models.base import ModelBase
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -66,19 +67,33 @@ class AdminSite(object):
If a model is already registered, this will raise AlreadyRegistered. If a model is already registered, this will raise AlreadyRegistered.
""" """
do_validate = admin_class and settings.DEBUG # Don't import the humongous validation code unless required
if do_validate: if admin_class and settings.DEBUG:
# don't import the humongous validation code unless required
from django.contrib.admin.validation import validate from django.contrib.admin.validation import validate
admin_class = admin_class or ModelAdmin else:
# TODO: Handle options validate = lambda model, adminclass: None
if not admin_class:
admin_class = ModelAdmin
if isinstance(model_or_iterable, ModelBase): if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable] model_or_iterable = [model_or_iterable]
for model in model_or_iterable: for model in model_or_iterable:
if model in self._registry: if model in self._registry:
raise AlreadyRegistered('The model %s is already registered' % model.__name__) raise AlreadyRegistered('The model %s is already registered' % model.__name__)
if do_validate:
validate(admin_class, model) # If we got **options then dynamically construct a subclass of
# admin_class with those **options.
if options:
# For reasons I don't quite understand, without a __module__
# the created class appears to "live" in the wrong place,
# which causes issues later on.
options['__module__'] = __name__
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
# Validate (which might be a no-op)
validate(admin_class, model)
# Instantiate the admin class to save in the registry
self._registry[model] = admin_class(model, self) self._registry[model] = admin_class(model, self)
def unregister(self, model_or_iterable): def unregister(self, model_or_iterable):

View File

@ -0,0 +1,64 @@
"""
Tests for various ways of registering models with the admin site.
"""
from django.db import models
from django.contrib import admin
class Person(models.Model):
name = models.CharField(max_length=200)
class Place(models.Model):
name = models.CharField(max_length=200)
__test__ = {'API_TESTS':"""
# Bare registration
>>> site = admin.AdminSite()
>>> site.register(Person)
>>> site._registry[Person]
<django.contrib.admin.options.ModelAdmin object at ...>
# Registration with a ModelAdmin
>>> site = admin.AdminSite()
>>> class NameAdmin(admin.ModelAdmin):
... list_display = ['name']
... save_on_top = True
>>> site.register(Person, NameAdmin)
>>> site._registry[Person]
<regressiontests.admin_registration.models.NameAdmin object at ...>
# You can't register the same model twice
>>> site.register(Person)
Traceback (most recent call last):
...
AlreadyRegistered: The model Person is already registered
# Registration using **options
>>> site = admin.AdminSite()
>>> site.register(Person, search_fields=['name'])
>>> site._registry[Person].search_fields
['name']
# With both admin_class and **options the **options override the fields in
# the admin class.
>>> site = admin.AdminSite()
>>> site.register(Person, NameAdmin, search_fields=["name"], list_display=['__str__'])
>>> site._registry[Person].search_fields
['name']
>>> site._registry[Person].list_display
['__str__']
>>> site._registry[Person].save_on_top
True
# You can also register iterables instead of single classes -- a nice shortcut
>>> site = admin.AdminSite()
>>> site.register([Person, Place], search_fields=['name'])
>>> site._registry[Person]
<django.contrib.admin.sites.PersonAdmin object at ...>
>>> site._registry[Place]
<django.contrib.admin.sites.PlaceAdmin object at ...>
"""}