1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +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) myappend('_' + item)
return "".join(res) 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): class ModelAdmin(object):
"Encapsulates all admin options and functionality for a given model." "Encapsulates all admin options and functionality for a given model."
@ -44,6 +81,7 @@ class ModelAdmin(object):
save_on_top = False save_on_top = False
ordering = None ordering = None
js = None js = None
fields = None
def __init__(self, model): def __init__(self, model):
self.model = model self.model = model
@ -74,6 +112,21 @@ class ModelAdmin(object):
else: else:
return self.change_view(request, unquote(url)) 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): def has_add_permission(self, request):
"Returns True if the given request has permission to add an object." "Returns True if the given request has permission to add an object."
opts = self.opts opts = self.opts
@ -173,7 +226,7 @@ class ModelAdmin(object):
if object_id_override is not None: if object_id_override is not None:
c['object_id'] = object_id_override 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): def change_view(self, request, object_id):
"The 'change' admin view for this model." "The 'change' admin view for this model."
@ -272,7 +325,7 @@ class ModelAdmin(object):
'original': manipulator.original_object, 'original': manipulator.original_object,
'is_popup': request.REQUEST.has_key('_popup'), '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): def change_list_view(self, request):
"The 'change list' admin view for this model." "The 'change list' admin view for this model."

View File

@ -41,8 +41,8 @@ def submit_row(context):
and 'onclick="submitOrderForm();"' or ''), and 'onclick="submitOrderForm();"' or ''),
'show_delete_link': (not is_popup and context['has_delete_permission'] 'show_delete_link': (not is_popup and context['has_delete_permission']
and (change or context['show_delete'])), and (change or context['show_delete'])),
'show_save_as_new': not is_popup and change and opts.ModelAdmin.save_as, '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.ModelAdmin.save_as or context['add']), '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_and_continue': not is_popup and context['has_change_permission'],
'show_save': True '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']) js.extend(['js/calendar.js', 'js/admin/DateTimeShortcuts.js'])
if opts.get_ordered_objects(): if opts.get_ordered_objects():
js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js']) js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
if opts.ModelAdmin.js: if opts.admin.js:
js.extend(opts.ModelAdmin.js) js.extend(opts.admin.js)
seen_collapse = False seen_collapse = False
for field_set in field_sets: for field_set in field_sets:
if not seen_collapse and 'collapse' in field_set.classes: 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)) 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 = model._meta.ModelAdmin(model) mav = model._meta.admin(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))
@ -166,11 +166,11 @@ class AdminBoundFieldSet(object):
def __len__(self): def __len__(self):
return len(self.bound_field_lines) 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 opts = model._meta
app_label = opts.app_label app_label = opts.app_label
auto_populated_fields = [f for f in opts.fields if f.prepopulate_from] 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) original = getattr(manipulator, 'original_object', None)
bound_field_sets = [field_set.bind(context['form'], original, AdminBoundFieldSet) for field_set in field_sets] 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(); 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, 'form_url': form_url,
'opts': opts, 'opts': opts,
'content_type_id': ContentType.objects.get_for_model(model).id, '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) context.update(extra_context)
return render_to_response([ return render_to_response([
@ -305,6 +305,7 @@ class ChangeList(object):
self.search_fields = search_fields self.search_fields = search_fields
self.list_select_related = list_select_related self.list_select_related = list_select_related
self.list_per_page = list_per_page self.list_per_page = list_per_page
self.model_admin = model_admin
# Get search parameters from the query string. # Get search parameters from the query string.
try: try:
@ -399,7 +400,7 @@ class ChangeList(object):
# then check the object's default ordering. If neither of those exist, # then check the object's default ordering. If neither of those exist,
# order descending by ID by default. Finally, look for manually-specified # order descending by ID by default. Finally, look for manually-specified
# ordering from the query string. # 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. # Normalize it to new-style ordering.
ordering = handle_legacy_orderlist(ordering) ordering = handle_legacy_orderlist(ordering)

View File

@ -979,14 +979,11 @@ def get_validation_errors(outfile, app=None):
# Check admin attribute. # Check admin attribute.
if opts.admin is not None: 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.')
else:
# list_display # list_display
if not isinstance(opts.ModelAdmin.list_display, (list, tuple)): 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.') e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')
else: else:
for fn in opts.ModelAdmin.list_display: for fn in opts.admin.list_display:
try: try:
f = opts.get_field(fn) f = opts.get_field(fn)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
@ -996,34 +993,34 @@ def get_validation_errors(outfile, app=None):
if isinstance(f, models.ManyToManyField): if isinstance(f, models.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn) e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_display_links # list_display_links
if opts.ModelAdmin.list_display_links and not opts.ModelAdmin.list_display: 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.') 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)): 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.') e.add(opts, '"admin.list_display_links", if given, must be set to a list or tuple.')
else: else:
for fn in opts.ModelAdmin.list_display_links: for fn in opts.admin.list_display_links:
try: try:
f = opts.get_field(fn) f = opts.get_field(fn)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
if not hasattr(cls, fn): if not hasattr(cls, fn):
e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % 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: 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) e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn)
# list_filter # list_filter
if not isinstance(opts.ModelAdmin.list_filter, (list, tuple)): 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.') e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else: else:
for fn in opts.ModelAdmin.list_filter: for fn in opts.admin.list_filter:
try: try:
f = opts.get_field(fn) f = opts.get_field(fn)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn) e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# date_hierarchy # date_hierarchy
if opts.ModelAdmin.date_hierarchy: if opts.admin.date_hierarchy:
try: try:
f = opts.get_field(opts.ModelAdmin.date_hierarchy) f = opts.get_field(opts.admin.date_hierarchy)
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.ModelAdmin.date_hierarchy) e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.admin.date_hierarchy)
# Check ordering attribute. # Check ordering attribute.
if opts.ordering: 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.loading import get_apps, get_app, get_models, get_model, register_models
from django.db.models.query import Q from django.db.models.query import Q
from django.db.models.manager import Manager 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 import *
from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED 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 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 import AutoField, ImageField, FieldDoesNotExist
from django.db.models.fields.related import OneToOneRel, ManyToOneRel from django.db.models.fields.related import OneToOneRel, ManyToOneRel
from django.db.models.query import delete_objects 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 import connection, backend, transaction
from django.db.models import signals from django.db.models import signals
from django.db.models.loading import register_models, get_model 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 # of both ModelAdmin and the 'class Admin' on this model. The
# resulting class is same as if the 'class Admin' were a subclass # resulting class is same as if the 'class Admin' were a subclass
# of ModelAdmin. # of ModelAdmin.
cls._meta.ModelAdmin = type('ModelAdmin', (value, ModelAdmin), {}) cls._meta.admin = 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)
elif hasattr(value, 'contribute_to_class'): elif hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name) value.contribute_to_class(cls, name)
else: else:

View File

@ -196,62 +196,3 @@ class Options(object):
else: else:
self._field_types[field_type] = False self._field_types[field_type] = False
return self._field_types[field_type] 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 from django.db import models
model_errors = "" 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): class ListDisplayBadOne(models.Model):
"Test list_display, list_display must be a list or tuple" "Test list_display, list_display must be a list or tuple"
first_name = models.CharField(maxlength=30) first_name = models.CharField(maxlength=30)