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

newforms-admin: Finished migrating AdminOptions to ModelForm. AdminOptions no longer exists. Things are still a bit messy.

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4343 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2007-01-17 05:39:29 +00:00
parent 4fc14c6f7a
commit d41320d2e5
8 changed files with 108 additions and 131 deletions

View File

@ -30,6 +30,43 @@ def unquote(s):
myappend('_' + item)
return "".join(res)
class AdminFieldSet(object):
def __init__(self, name, classes, field_locator_func, line_specs, description):
self.name = name
self.field_lines = [AdminFieldLine(field_locator_func, line_spec) for line_spec in line_specs]
self.classes = classes
self.description = description
def __repr__(self):
return "FieldSet: (%s, %s)" % (self.name, self.field_lines)
def bind(self, field_mapping, original, bound_field_set_class):
return bound_field_set_class(self, field_mapping, original)
def __iter__(self):
for field_line in self.field_lines:
yield field_line
def __len__(self):
return len(self.field_lines)
class AdminFieldLine(object):
def __init__(self, field_locator_func, linespec):
if isinstance(linespec, basestring):
self.fields = [field_locator_func(linespec)]
else:
self.fields = [field_locator_func(field_name) for field_name in linespec]
def bind(self, field_mapping, original, bound_field_line_class):
return bound_field_line_class(self, field_mapping, original)
def __iter__(self):
for field in self.fields:
yield field
def __len__(self):
return len(self.fields)
class ModelAdmin(object):
"Encapsulates all admin options and functionality for a given model."
@ -44,6 +81,7 @@ class ModelAdmin(object):
save_on_top = False
ordering = None
js = None
fields = None
def __init__(self, model):
self.model = model
@ -74,6 +112,21 @@ class ModelAdmin(object):
else:
return self.change_view(request, unquote(url))
def get_field_sets(self, opts):
"Returns a list of AdminFieldSet objects."
if self.fields is None:
field_struct = ((None, {'fields': [f.name for f in opts.fields + opts.many_to_many if f.editable and not isinstance(f, models.AutoField)]}),)
else:
field_struct = self.fields
new_fieldset_list = []
for fieldset in field_struct:
fs_options = fieldset[1]
classes = fs_options.get('classes', ())
description = fs_options.get('description', '')
new_fieldset_list.append(AdminFieldSet(fieldset[0], classes,
opts.get_field, fs_options['fields'], description))
return new_fieldset_list
def has_add_permission(self, request):
"Returns True if the given request has permission to add an object."
opts = self.opts
@ -173,7 +226,7 @@ class ModelAdmin(object):
if object_id_override is not None:
c['object_id'] = object_id_override
return render_change_form(model, manipulator, c, add=True)
return render_change_form(self, model, manipulator, c, add=True)
def change_view(self, request, object_id):
"The 'change' admin view for this model."
@ -272,7 +325,7 @@ class ModelAdmin(object):
'original': manipulator.original_object,
'is_popup': request.REQUEST.has_key('_popup'),
})
return render_change_form(model, manipulator, c, change=True)
return render_change_form(self, model, manipulator, c, change=True)
def change_list_view(self, request):
"The 'change list' admin view for this model."

View File

@ -41,8 +41,8 @@ def submit_row(context):
and 'onclick="submitOrderForm();"' or ''),
'show_delete_link': (not is_popup and context['has_delete_permission']
and (change or context['show_delete'])),
'show_save_as_new': not is_popup and change and opts.ModelAdmin.save_as,
'show_save_and_add_another': not is_popup and (not opts.ModelAdmin.save_as or context['add']),
'show_save_as_new': not is_popup and change and opts.admin.save_as,
'show_save_and_add_another': not is_popup and (not opts.admin.save_as or context['add']),
'show_save_and_continue': not is_popup and context['has_change_permission'],
'show_save': True
}

View File

@ -57,8 +57,8 @@ def get_javascript_imports(opts, auto_populated_fields, field_sets):
js.extend(['js/calendar.js', 'js/admin/DateTimeShortcuts.js'])
if opts.get_ordered_objects():
js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
if opts.ModelAdmin.js:
js.extend(opts.ModelAdmin.js)
if opts.admin.js:
js.extend(opts.admin.js)
seen_collapse = False
for field_set in field_sets:
if not seen_collapse and 'collapse' in field_set.classes:
@ -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))
if not model._meta.admin:
raise Http404("This object has no admin interface.")
mav = model._meta.ModelAdmin(model)
mav = model._meta.admin(model)
return mav(request, rest_of_url)
model_admin_view = staff_member_required(never_cache(model_admin_view))
@ -166,11 +166,11 @@ class AdminBoundFieldSet(object):
def __len__(self):
return len(self.bound_field_lines)
def render_change_form(model, manipulator, context, add=False, change=False, form_url=''):
def render_change_form(model_admin, model, manipulator, context, add=False, change=False, form_url=''):
opts = model._meta
app_label = opts.app_label
auto_populated_fields = [f for f in opts.fields if f.prepopulate_from]
field_sets = opts.admin.get_field_sets(opts)
field_sets = model_admin.get_field_sets(opts)
original = getattr(manipulator, 'original_object', None)
bound_field_sets = [field_set.bind(context['form'], original, AdminBoundFieldSet) for field_set in field_sets]
first_form_field_id = bound_field_sets[0].bound_field_lines[0].bound_fields[0].form_fields[0].get_id();
@ -192,7 +192,7 @@ def render_change_form(model, manipulator, context, add=False, change=False, for
'form_url': form_url,
'opts': opts,
'content_type_id': ContentType.objects.get_for_model(model).id,
'save_on_top': opts.ModelAdmin.save_on_top,
'save_on_top': model_admin.save_on_top,
}
context.update(extra_context)
return render_to_response([
@ -305,6 +305,7 @@ class ChangeList(object):
self.search_fields = search_fields
self.list_select_related = list_select_related
self.list_per_page = list_per_page
self.model_admin = model_admin
# Get search parameters from the query string.
try:
@ -399,7 +400,7 @@ class ChangeList(object):
# then check the object's default ordering. If neither of those exist,
# order descending by ID by default. Finally, look for manually-specified
# ordering from the query string.
ordering = lookup_opts.ModelAdmin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
# Normalize it to new-style ordering.
ordering = handle_legacy_orderlist(ordering)

View File

@ -979,51 +979,48 @@ def get_validation_errors(outfile, app=None):
# Check admin attribute.
if opts.admin is not None:
if not isinstance(opts.admin, models.AdminOptions):
e.add(opts, '"admin" attribute, if given, must be set to a models.AdminOptions() instance.')
# list_display
if not isinstance(opts.admin.list_display, (list, tuple)):
e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')
else:
# list_display
if not isinstance(opts.ModelAdmin.list_display, (list, tuple)):
e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')
else:
for fn in opts.ModelAdmin.list_display:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
if not hasattr(cls, fn):
e.add(opts, '"admin.list_display" refers to %r, which isn\'t an attribute, method or property.' % fn)
else:
if isinstance(f, models.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_display_links
if opts.ModelAdmin.list_display_links and not opts.ModelAdmin.list_display:
e.add(opts, '"admin.list_display" must be defined for "admin.list_display_links" to be used.')
if not isinstance(opts.ModelAdmin.list_display_links, (list, tuple)):
e.add(opts, '"admin.list_display_links", if given, must be set to a list or tuple.')
else:
for fn in opts.ModelAdmin.list_display_links:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
if not hasattr(cls, fn):
e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % fn)
if fn not in opts.ModelAdmin.list_display:
e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn)
# list_filter
if not isinstance(opts.ModelAdmin.list_filter, (list, tuple)):
e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else:
for fn in opts.ModelAdmin.list_filter:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# date_hierarchy
if opts.ModelAdmin.date_hierarchy:
for fn in opts.admin.list_display:
try:
f = opts.get_field(opts.ModelAdmin.date_hierarchy)
f = opts.get_field(fn)
except models.FieldDoesNotExist:
e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.ModelAdmin.date_hierarchy)
if not hasattr(cls, fn):
e.add(opts, '"admin.list_display" refers to %r, which isn\'t an attribute, method or property.' % fn)
else:
if isinstance(f, models.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_display_links
if opts.admin.list_display_links and not opts.admin.list_display:
e.add(opts, '"admin.list_display" must be defined for "admin.list_display_links" to be used.')
if not isinstance(opts.admin.list_display_links, (list, tuple)):
e.add(opts, '"admin.list_display_links", if given, must be set to a list or tuple.')
else:
for fn in opts.admin.list_display_links:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
if not hasattr(cls, fn):
e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % fn)
if fn not in opts.admin.list_display:
e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn)
# list_filter
if not isinstance(opts.admin.list_filter, (list, tuple)):
e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else:
for fn in opts.admin.list_filter:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# date_hierarchy
if opts.admin.date_hierarchy:
try:
f = opts.get_field(opts.admin.date_hierarchy)
except models.FieldDoesNotExist:
e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.admin.date_hierarchy)
# Check ordering attribute.
if opts.ordering:

View File

@ -5,7 +5,7 @@ from django.db import backend, connection
from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models
from django.db.models.query import Q
from django.db.models.manager import Manager
from django.db.models.base import Model, AdminOptions
from django.db.models.base import Model
from django.db.models.fields import *
from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED
from django.db.models.fields.generic import GenericRelation, GenericRel, GenericForeignKey

View File

@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
from django.db.models.fields.related import OneToOneRel, ManyToOneRel
from django.db.models.query import delete_objects
from django.db.models.options import Options, AdminOptions
from django.db.models.options import Options
from django.db import connection, backend, transaction
from django.db.models import signals
from django.db.models.loading import register_models, get_model
@ -135,10 +135,7 @@ class Model(object):
# 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('_') and k not in ('list_display', 'list_display_links', 'list_filter', 'date_hierarchy', 'save_as', 'search_fields', 'list_select_related', 'list_per_page', 'ordering', 'save_on_top', 'js', 'manager')]))
value.contribute_to_class(cls, name)
cls._meta.admin = type('ModelAdmin', (value, ModelAdmin), {})
elif hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name)
else:

View File

@ -196,62 +196,3 @@ class Options(object):
else:
self._field_types[field_type] = False
return self._field_types[field_type]
class AdminOptions(object):
def __init__(self, fields=None):
self.fields = fields
def get_field_sets(self, opts):
"Returns a list of AdminFieldSet objects for this AdminOptions object."
if self.fields is None:
field_struct = ((None, {'fields': [f.name for f in opts.fields + opts.many_to_many if f.editable and not isinstance(f, AutoField)]}),)
else:
field_struct = self.fields
new_fieldset_list = []
for fieldset in field_struct:
fs_options = fieldset[1]
classes = fs_options.get('classes', ())
description = fs_options.get('description', '')
new_fieldset_list.append(AdminFieldSet(fieldset[0], classes,
opts.get_field, fs_options['fields'], description))
return new_fieldset_list
def contribute_to_class(self, cls, name):
cls._meta.admin = self
class AdminFieldSet(object):
def __init__(self, name, classes, field_locator_func, line_specs, description):
self.name = name
self.field_lines = [AdminFieldLine(field_locator_func, line_spec) for line_spec in line_specs]
self.classes = classes
self.description = description
def __repr__(self):
return "FieldSet: (%s, %s)" % (self.name, self.field_lines)
def bind(self, field_mapping, original, bound_field_set_class):
return bound_field_set_class(self, field_mapping, original)
def __iter__(self):
for field_line in self.field_lines:
yield field_line
def __len__(self):
return len(self.field_lines)
class AdminFieldLine(object):
def __init__(self, field_locator_func, linespec):
if isinstance(linespec, basestring):
self.fields = [field_locator_func(linespec)]
else:
self.fields = [field_locator_func(field_name) for field_name in linespec]
def bind(self, field_mapping, original, bound_field_line_class):
return bound_field_line_class(self, field_mapping, original)
def __iter__(self):
for field in self.fields:
yield field
def __len__(self):
return len(self.fields)

View File

@ -8,18 +8,6 @@ model validation is working properly.
from django.db import models
model_errors = ""
# TODO: Invalid admin options should not cause a metaclass error
##This should fail gracefully but is causing a metaclass error
#class BadAdminOption(models.Model):
# "Test nonexistent admin option"
# name = models.CharField(maxlength=30)
#
# class Admin:
# nonexistent = 'option'
#
#model_errors += """invalid_admin_options.badadminoption: "admin" attribute, if given, must be set to a models.AdminOptions() instance.
#"""
class ListDisplayBadOne(models.Model):
"Test list_display, list_display must be a list or tuple"
first_name = models.CharField(maxlength=30)
@ -334,4 +322,4 @@ class OrderingBad(models.Model):
# manager = 'nonexistent'
#
#model_errors += """invalid_admin_options.managerbad: "admin.manager" refers to 'nonexistent', which isn't a Manager().
#"""
#"""