Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit 7b3cf13d3249d4e4bcf152e27631ea7ec4a55412 1 parent 508016c
@jacobian jacobian authored
View
29 django/contrib/admin/sites.py
@@ -1,6 +1,7 @@
from django import http, template
from django.contrib.admin import ModelAdmin
from django.contrib.auth import authenticate, login
+from django.core.exceptions import ImproperlyConfigured
from django.db.models.base import ModelBase
from django.shortcuts import render_to_response
from django.utils.safestring import mark_safe
@@ -66,19 +67,33 @@ def register(self, model_or_iterable, admin_class=None, **options):
If a model is already registered, this will raise AlreadyRegistered.
"""
- do_validate = admin_class and settings.DEBUG
- if do_validate:
- # don't import the humongous validation code unless required
+ # Don't import the humongous validation code unless required
+ if admin_class and settings.DEBUG:
from django.contrib.admin.validation import validate
- admin_class = admin_class or ModelAdmin
- # TODO: Handle options
+ else:
+ validate = lambda model, adminclass: None
+
+ if not admin_class:
+ admin_class = ModelAdmin
if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable:
if model in self._registry:
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)
def unregister(self, model_or_iterable):
View
0  tests/regressiontests/admin_registration/__init__.py
No changes.
View
64 tests/regressiontests/admin_registration/models.py
@@ -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 ...>
+
+"""}
Please sign in to comment.
Something went wrong with that request. Please try again.