1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

newforms-admin: A model's 'class Admin' is now dynamically/magically converted to be a subclass of django.contrib.admin.options.ModelAdmin, and the admin site now uses that class rather than the separate AdminOptions class (for list_display only). This means means 'class Admin' can override any functionality of ModelAdmin, such as has_add_permission(), etc.

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4328 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2007-01-16 00:09:53 +00:00
parent ede911b5a2
commit 560a1ba9a0
5 changed files with 23 additions and 11 deletions

View File

@ -32,6 +32,9 @@ def unquote(s):
class ModelAdmin(object): class ModelAdmin(object):
"Encapsulates all admin options and functionality for a given model." "Encapsulates all admin options and functionality for a given model."
list_display = ('__str__',)
def __init__(self, model): def __init__(self, model):
self.model = model self.model = model
self.opts = model._meta self.opts = model._meta
@ -266,7 +269,7 @@ class ModelAdmin(object):
if not self.has_change_permission(request, None): if not self.has_change_permission(request, None):
raise PermissionDenied raise PermissionDenied
try: try:
cl = ChangeList(request, self.model) cl = ChangeList(request, self.model, self.list_display)
except IncorrectLookupParameters: except IncorrectLookupParameters:
# Wacky lookup parameters were given, so redirect to the main # Wacky lookup parameters were given, so redirect to the main
# changelist page, without parameters, and pass an 'invalid=1' # changelist page, without parameters, and pass an 'invalid=1'

View File

@ -69,7 +69,7 @@ pagination = register.inclusion_tag('admin/pagination.html')(pagination)
def result_headers(cl): def result_headers(cl):
lookup_opts = cl.lookup_opts lookup_opts = cl.lookup_opts
for i, field_name in enumerate(lookup_opts.admin.list_display): for i, field_name in enumerate(cl.list_display):
try: try:
f = lookup_opts.get_field(field_name) f = lookup_opts.get_field(field_name)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
@ -108,7 +108,7 @@ def _boolean_icon(field_val):
def items_for_result(cl, result): def items_for_result(cl, result):
first = True first = True
pk = cl.lookup_opts.pk.attname pk = cl.lookup_opts.pk.attname
for field_name in cl.lookup_opts.admin.list_display: for field_name in cl.list_display:
row_class = '' row_class = ''
try: try:
f = cl.lookup_opts.get_field(field_name) f = cl.lookup_opts.get_field(field_name)
@ -172,7 +172,7 @@ def items_for_result(cl, result):
if result_repr == '': if result_repr == '':
result_repr = ' ' result_repr = ' '
# If list_display_links not defined, add the link tag to the first field # If list_display_links not defined, add the link tag to the first field
if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links: if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
table_tag = {True:'th', False:'td'}[first] table_tag = {True:'th', False:'td'}[first]
first = False first = False
url = cl.url_for_result(result) url = cl.url_for_result(result)

View File

@ -81,7 +81,7 @@ def model_admin_view(request, app_label, model_name, rest_of_url):
raise Http404("App %r, model %r, not found" % (app_label, model_name)) raise Http404("App %r, model %r, not found" % (app_label, model_name))
if not model._meta.admin: if not model._meta.admin:
raise Http404("This object has no admin interface.") raise Http404("This object has no admin interface.")
mav = ModelAdmin(model) mav = model._meta.ModelAdmin(model)
return mav(request, rest_of_url) return mav(request, rest_of_url)
model_admin_view = staff_member_required(never_cache(model_admin_view)) model_admin_view = staff_member_required(never_cache(model_admin_view))
@ -292,11 +292,12 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
perms_needed.add(related.opts.verbose_name) perms_needed.add(related.opts.verbose_name)
class ChangeList(object): class ChangeList(object):
def __init__(self, request, model): def __init__(self, request, model, list_display):
self.model = model self.model = model
self.opts = model._meta self.opts = model._meta
self.lookup_opts = self.opts self.lookup_opts = self.opts
self.manager = self.opts.admin.manager self.manager = self.opts.admin.manager
self.list_display = list_display
# Get search parameters from the query string. # Get search parameters from the query string.
try: try:
@ -404,7 +405,7 @@ class ChangeList(object):
if params.has_key(ORDER_VAR): if params.has_key(ORDER_VAR):
try: try:
try: try:
f = lookup_opts.get_field(lookup_opts.admin.list_display[int(params[ORDER_VAR])]) f = lookup_opts.get_field(self.list_display[int(params[ORDER_VAR])])
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
pass pass
else: else:
@ -431,7 +432,7 @@ class ChangeList(object):
if self.lookup_opts.admin.list_select_related: if self.lookup_opts.admin.list_select_related:
qs = qs.select_related() qs = qs.select_related()
else: else:
for field_name in self.lookup_opts.admin.list_display: for field_name in self.list_display:
try: try:
f = self.lookup_opts.get_field(field_name) f = self.lookup_opts.get_field(field_name)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:

View File

@ -130,8 +130,16 @@ class Model(object):
def add_to_class(cls, name, value): def add_to_class(cls, name, value):
if name == 'Admin': if name == 'Admin':
assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value)) assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value))
from django.contrib.admin.options import ModelAdmin
# Dynamically create a new ModelAdmin class, which is a subclass
# of both ModelAdmin and the 'class Admin' on this model. The
# resulting class is same as if the 'class Admin' were a subclass
# of ModelAdmin.
cls._meta.ModelAdmin = type('ModelAdmin', (value, ModelAdmin), {})
# This AdminOptions stuff is legacy and will eventually be removed.
value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() if not k.startswith('_')])) value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() if not k.startswith('_')]))
if hasattr(value, 'contribute_to_class'): value.contribute_to_class(cls, name)
elif hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name) value.contribute_to_class(cls, name)
else: else:
setattr(cls, name, value) setattr(cls, name, value)

View File

@ -87,10 +87,10 @@ class Options(object):
def __repr__(self): def __repr__(self):
return '<Options for %s>' % self.object_name return '<Options for %s>' % self.object_name
def __str__(self): def __str__(self):
return "%s.%s" % (self.app_label, self.module_name) return "%s.%s" % (self.app_label, self.module_name)
def get_field(self, name, many_to_many=True): def get_field(self, name, many_to_many=True):
"Returns the requested field by name. Raises FieldDoesNotExist on error." "Returns the requested field by name. Raises FieldDoesNotExist on error."
to_search = many_to_many and (self.fields + self.many_to_many) or self.fields to_search = many_to_many and (self.fields + self.many_to_many) or self.fields