mirror of https://github.com/django/django.git
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:
parent
508016c0f4
commit
7b3cf13d32
|
@ -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):
|
||||||
|
|
|
@ -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 ...>
|
||||||
|
|
||||||
|
"""}
|
Loading…
Reference in New Issue