mirror of
https://github.com/django/django.git
synced 2025-06-13 15:39:13 +00:00
Changes to get admin semi-working
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1675 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
bc1cef4e7b
commit
8b857e8044
@ -190,8 +190,8 @@ result_list = register.inclusion_tag("admin/change_list_results")(result_list)
|
||||
|
||||
#@register.inclusion_tag("admin/date_hierarchy")
|
||||
def date_hierarchy(cl):
|
||||
lookup_opts, params, lookup_params, lookup_mod = \
|
||||
cl.lookup_opts, cl.params, cl.lookup_params, cl.lookup_mod
|
||||
lookup_opts, params, lookup_params, manager = \
|
||||
cl.lookup_opts, cl.params, cl.lookup_params, cl.manager
|
||||
|
||||
if lookup_opts.admin.date_hierarchy:
|
||||
field_name = lookup_opts.admin.date_hierarchy
|
||||
@ -208,7 +208,7 @@ def date_hierarchy(cl):
|
||||
return cl.get_query_string(d, [field_generic])
|
||||
|
||||
def get_dates(unit, params):
|
||||
return getattr(lookup_mod, 'get_%s_list' % field_name)(unit, **params)
|
||||
return getattr(manager, 'get_%s_list' % field_name)(unit, **params)
|
||||
|
||||
if year_lookup and month_lookup and day_lookup:
|
||||
month_name = MONTHS[int(month_lookup)]
|
||||
|
@ -17,6 +17,8 @@ class AdminApplistNode(template.Node):
|
||||
has_module_perms = user.has_module_perms(app_label)
|
||||
if has_module_perms:
|
||||
model_list = []
|
||||
#HACK
|
||||
app_url = "/".join( [comp for comp in app.__name__.split('.') if comp != 'models' ])
|
||||
for m in app._MODELS:
|
||||
if m._meta.admin:
|
||||
module_name = m._meta.module_name
|
||||
@ -28,10 +30,12 @@ class AdminApplistNode(template.Node):
|
||||
|
||||
# Check whether user has any perm for this module.
|
||||
# If so, add the module to the model_list.
|
||||
|
||||
|
||||
if True in perms.values():
|
||||
model_list.append({
|
||||
'name': capfirst(m._meta.verbose_name_plural),
|
||||
'admin_url': '%s/%s/' % (app_label, m._meta.module_name),
|
||||
'admin_url': '%s/%s/' % (app_url, m.__name__.lower()),
|
||||
'perms': perms,
|
||||
})
|
||||
|
||||
|
@ -48,11 +48,10 @@ if 'ellington.media' in INSTALLED_APPS:
|
||||
)
|
||||
|
||||
urlpatterns += (
|
||||
# Metasystem admin pages
|
||||
('^(?P<app_label>[^/]+)/(?P<module_name>[^/]+)/$', 'django.contrib.admin.views.main.change_list'),
|
||||
('^(?P<app_label>[^/]+)/(?P<module_name>[^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
|
||||
('^(?P<app_label>[^/]+)/(?P<module_name>[^/]+)/(?P<object_id>.+)/history/$', 'django.contrib.admin.views.main.history'),
|
||||
('^(?P<app_label>[^/]+)/(?P<module_name>[^/]+)/(?P<object_id>.+)/delete/$', 'django.contrib.admin.views.main.delete_stage'),
|
||||
('^(?P<app_label>[^/]+)/(?P<module_name>[^/]+)/(?P<object_id>.+)/$', 'django.contrib.admin.views.main.change_stage'),
|
||||
('^((?:[^/]+/)+?)add/$', 'django.contrib.admin.views.main.add_stage'),
|
||||
('^((?:[^/]+/)+?)([^/]+)/history/$', 'django.contrib.admin.views.main.history'),
|
||||
('^((?:[^/]+/)+?)([^/]+)/delete/$', 'django.contrib.admin.views.main.delete_stage'),
|
||||
('^((?:[^/]+/)+?)([^/]+)/change/$', 'django.contrib.admin.views.main.change_stage'),
|
||||
('^((?:[^/]+/)+?)$', 'django.contrib.admin.views.main.change_list' ),
|
||||
)
|
||||
urlpatterns = patterns('', *urlpatterns)
|
||||
|
@ -1,4 +1,5 @@
|
||||
# Generic admin views.
|
||||
from django.conf import settings
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.contrib.admin.filterspecs import FilterSpec
|
||||
from django.core import formfields, template
|
||||
@ -21,6 +22,7 @@ from django.utils import dateformat
|
||||
from django.utils.dates import MONTHS
|
||||
from django.utils.html import escape
|
||||
import operator
|
||||
from itertools import izip
|
||||
|
||||
# The system will display a "Show all" link only if the total result count
|
||||
# is less than or equal to this setting.
|
||||
@ -41,7 +43,7 @@ EMPTY_CHANGELIST_VALUE = '(None)'
|
||||
def _get_mod_opts(app_label, module_name):
|
||||
"Helper function that returns a tuple of (module, opts), raising Http404 if necessary."
|
||||
try:
|
||||
mod = models.get_module(app_label, module_name)
|
||||
mod = models.get_app(app_label)
|
||||
except ImportError:
|
||||
raise Http404 # Invalid app or module name. Maybe it's not in INSTALLED_APPS.
|
||||
opts = mod.Klass._meta
|
||||
@ -49,6 +51,52 @@ def _get_mod_opts(app_label, module_name):
|
||||
raise Http404 # This object is valid but has no admin interface.
|
||||
return mod, opts
|
||||
|
||||
def matches_app(mod, comps):
|
||||
modcomps = mod.__name__.split('.')[:-1] #HACK: leave off 'models'
|
||||
for c, mc in izip(comps, modcomps):
|
||||
if c != mc:
|
||||
return ([],False)
|
||||
return (comps[len(modcomps):], True)
|
||||
|
||||
def find_model(mod, remaining):
|
||||
# print "finding ", mod, remaining
|
||||
if len(remaining) == 0:
|
||||
# print "no comps left"
|
||||
raise Http404
|
||||
if len(remaining) == 1:
|
||||
if hasattr(mod, '_MODELS'):
|
||||
name = remaining[0]
|
||||
for model in mod._MODELS:
|
||||
print "'%s'" % name, model
|
||||
if model.__name__.lower() == name:
|
||||
return model
|
||||
raise Http404
|
||||
else:
|
||||
raise Http404
|
||||
else:
|
||||
child = getattr(mod, remaining[0], None)
|
||||
# print mod, remaining[0], child
|
||||
if child:
|
||||
return find_model(child, remaining[1:])
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
def get_app_label(mod):
|
||||
modcomps = mod.__name__.split('.')
|
||||
return modcomps[-2]
|
||||
|
||||
def get_model_and_app(path):
|
||||
comps = path.split('/')
|
||||
comps = comps[:-1] # remove '' after final /
|
||||
for mod in models.get_installed_models():
|
||||
remaining, matched = matches_app(mod, comps)
|
||||
if matched and len(remaining) > 0:
|
||||
# print "matched ", mod
|
||||
# print "left", remaining
|
||||
return ( find_model(mod, remaining), get_app_label(mod) )
|
||||
|
||||
raise Http404 # Couldn't find app
|
||||
|
||||
def index(request):
|
||||
return render_to_response('admin/index', {'title': _('Site administration')}, context_instance=Context(request))
|
||||
index = staff_member_required(index)
|
||||
@ -57,8 +105,8 @@ class IncorrectLookupParameters(Exception):
|
||||
pass
|
||||
|
||||
class ChangeList(object):
|
||||
def __init__(self, request, app_label, module_name):
|
||||
self.get_modules_and_options(app_label, module_name, request)
|
||||
def __init__(self, request, path):
|
||||
self.resolve_model(path, request)
|
||||
self.get_search_parameters(request)
|
||||
self.get_ordering()
|
||||
self.query = request.GET.get(SEARCH_VAR, '')
|
||||
@ -94,12 +142,16 @@ class ChangeList(object):
|
||||
p[k] = v
|
||||
return '?' + '&'.join(['%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
|
||||
|
||||
def get_modules_and_options(self, app_label, module_name, request):
|
||||
self.mod, self.opts = _get_mod_opts(app_label, module_name)
|
||||
if not request.user.has_perm(app_label + '.' + self.opts.get_change_permission()):
|
||||
def resolve_model(self, path, request):
|
||||
self.model, self.app_label = get_model_and_app(path)
|
||||
# _get_mod_opts(app_label, module_name)
|
||||
self.opts = self.model._meta
|
||||
|
||||
if not request.user.has_perm(self.app_label + '.' + self.opts.get_change_permission()):
|
||||
raise PermissionDenied
|
||||
|
||||
self.lookup_mod, self.lookup_opts = self.mod, self.opts
|
||||
self.lookup_opts = self.opts
|
||||
self.manager = self.model._default_manager
|
||||
|
||||
def get_search_parameters(self, request):
|
||||
# Get search parameters from the query string.
|
||||
@ -114,11 +166,11 @@ class ChangeList(object):
|
||||
del self.params[PAGE_VAR]
|
||||
|
||||
def get_results(self, request):
|
||||
lookup_mod, lookup_params, show_all, page_num = \
|
||||
self.lookup_mod, self.lookup_params, self.show_all, self.page_num
|
||||
manager, lookup_params, show_all, page_num = \
|
||||
self.manager, self.lookup_params, self.show_all, self.page_num
|
||||
# Get the results.
|
||||
try:
|
||||
paginator = ObjectPaginator(lookup_mod, lookup_params, DEFAULT_RESULTS_PER_PAGE)
|
||||
paginator = ObjectPaginator(manager, lookup_params, DEFAULT_RESULTS_PER_PAGE)
|
||||
# Naked except! Because we don't have any other way of validating "params".
|
||||
# They might be invalid if the keyword arguments are incorrect, or if the
|
||||
# values are not in the correct type (which would result in a database
|
||||
@ -130,7 +182,7 @@ class ChangeList(object):
|
||||
real_lookup_params = lookup_params.copy()
|
||||
del real_lookup_params['order_by']
|
||||
if real_lookup_params:
|
||||
full_result_count = lookup_mod.get_count()
|
||||
full_result_count = manager.get_count()
|
||||
else:
|
||||
full_result_count = paginator.hits
|
||||
del real_lookup_params
|
||||
@ -140,7 +192,7 @@ class ChangeList(object):
|
||||
|
||||
# Get the list of objects to display on this page.
|
||||
if (show_all and can_show_all) or not multi_page:
|
||||
result_list = lookup_mod.get_list(**lookup_params)
|
||||
result_list = manager.get_list(**lookup_params)
|
||||
else:
|
||||
try:
|
||||
result_list = paginator.get_page(page_num)
|
||||
@ -231,9 +283,10 @@ class ChangeList(object):
|
||||
lookup_params.update(opts.one_to_one_field.rel.limit_choices_to)
|
||||
self.lookup_params = lookup_params
|
||||
|
||||
def change_list(request, app_label, module_name):
|
||||
def change_list(request, path):
|
||||
print "change_list:", path
|
||||
try:
|
||||
cl = ChangeList(request, app_label, module_name)
|
||||
cl = ChangeList(request, path)
|
||||
except IncorrectLookupParameters:
|
||||
return HttpResponseRedirect(request.path)
|
||||
|
||||
@ -242,9 +295,9 @@ def change_list(request, app_label, module_name):
|
||||
'is_popup': cl.is_popup,
|
||||
'cl' : cl
|
||||
})
|
||||
c.update({'has_add_permission': c['perms'][app_label][cl.opts.get_add_permission()]}),
|
||||
return render_to_response(['admin/%s/%s/change_list' % (app_label, cl.opts.object_name.lower()),
|
||||
'admin/%s/change_list' % app_label,
|
||||
c.update({'has_add_permission': c['perms'][cl.app_label][cl.opts.get_add_permission()]}),
|
||||
return render_to_response(['admin/%s/%s/change_list' % (cl.app_label, cl.opts.object_name.lower()),
|
||||
'admin/%s/change_list' % cl.app_label,
|
||||
'admin/change_list'], context_instance=c)
|
||||
change_list = staff_member_required(change_list)
|
||||
|
||||
@ -464,12 +517,15 @@ def log_change_message(user, opts,manipulator,new_object):
|
||||
change_message = _('No fields changed.')
|
||||
LogEntry.objects.log_action(user.id, opts.get_content_type_id(), pk_value, str(new_object), CHANGE, change_message)
|
||||
|
||||
def change_stage(request, app_label, module_name, object_id):
|
||||
mod, opts = _get_mod_opts(app_label, module_name)
|
||||
def change_stage(request, path, object_id):
|
||||
print "change_stage", path, object_id
|
||||
model, app_label = get_model_and_app(path)
|
||||
opts = model._meta
|
||||
#mod, opts = _get_mod_opts(app_label, module_name)
|
||||
if not request.user.has_perm(app_label + '.' + opts.get_change_permission()):
|
||||
raise PermissionDenied
|
||||
if request.POST and request.POST.has_key("_saveasnew"):
|
||||
return add_stage(request, app_label, module_name, form_url='../add/')
|
||||
return add_stage(request, path, form_url='../add/')
|
||||
try:
|
||||
manipulator = mod.ChangeManipulator(object_id)
|
||||
except ObjectDoesNotExist:
|
||||
|
@ -1,23 +1,28 @@
|
||||
from copy import copy
|
||||
from math import ceil
|
||||
from django.db.models import ModelBase
|
||||
|
||||
class InvalidPage(Exception):
|
||||
pass
|
||||
|
||||
class ObjectPaginator:
|
||||
"""
|
||||
This class makes pagination easy. Feed it a module (an object with
|
||||
get_count() and get_list() methods) and a dictionary of arguments
|
||||
to be passed to those methods, plus the number of objects you want
|
||||
on each page. Then read the hits and pages properties to see how
|
||||
many pages it involves. Call get_page with a page number (starting
|
||||
at 0) to get back a list of objects for that page.
|
||||
This class makes pagination easy. Feed it a manager (an object with
|
||||
get_count() and get_list() methods) or a model which has a default manager,
|
||||
and a dictionary of arguments to be passed to those methods, plus the
|
||||
number of objects you want on each page. Then read the hits and pages
|
||||
properties to see how many pages it involves. Call get_page with a page
|
||||
number (starting at 0) to get back a list of objects for that page.
|
||||
|
||||
Finally, check if a page number has a next/prev page using
|
||||
has_next_page(page_number) and has_previous_page(page_number).
|
||||
"""
|
||||
def __init__(self, module, args, num_per_page, count_method='get_count', list_method='get_list'):
|
||||
self.module, self.args = module, args
|
||||
def __init__(self, manager_or_model, args, num_per_page, count_method='get_count', list_method='get_list'):
|
||||
if hasattr(manager_or_model, '_default_manager'):
|
||||
manager = manager_or_model._default_manager
|
||||
else:
|
||||
manager = manager_or_model
|
||||
self.manager, self.args = manager, args
|
||||
self.num_per_page = num_per_page
|
||||
self.count_method, self.list_method = count_method, list_method
|
||||
self._hits, self._pages = None, None
|
||||
@ -35,7 +40,7 @@ class ObjectPaginator:
|
||||
# Retrieve one extra record, and check for the existence of that extra
|
||||
# record to determine whether there's a next page.
|
||||
args['limit'] = self.num_per_page + 1
|
||||
object_list = getattr(self.module, self.list_method)(**args)
|
||||
object_list = getattr(self.manager, self.list_method)(**args)
|
||||
if not object_list:
|
||||
raise InvalidPage
|
||||
self._has_next[page_number] = (len(object_list) > self.num_per_page)
|
||||
@ -48,7 +53,7 @@ class ObjectPaginator:
|
||||
args = copy(self.args)
|
||||
args['offset'] = (page_number + 1) * self.num_per_page
|
||||
args['limit'] = 1
|
||||
object_list = getattr(self.module, self.list_method)(**args)
|
||||
object_list = getattr(self.manager, self.list_method)(**args)
|
||||
self._has_next[page_number] = (object_list != [])
|
||||
else:
|
||||
self._has_next[page_number] = page_number < (self.pages - 1)
|
||||
@ -64,7 +69,7 @@ class ObjectPaginator:
|
||||
del order_args['order_by']
|
||||
if order_args.has_key('select_related'):
|
||||
del order_args['select_related']
|
||||
self._hits = getattr(self.module, self.count_method)(**order_args)
|
||||
self._hits = getattr(self.manager, self.count_method)(**order_args)
|
||||
return self._hits
|
||||
|
||||
def _get_pages(self):
|
||||
|
@ -1051,6 +1051,17 @@ class Model(object):
|
||||
|
||||
delete.alters_data = True
|
||||
|
||||
def __get_add_manipulator(cls):
|
||||
cls.AddManipulator = get_manipulator
|
||||
|
||||
AddManipulator = property(classmethod(__get_add_manipulator))
|
||||
|
||||
def __get_change_manipulator(cls):
|
||||
|
||||
ChangeManipulator = property(classmethod(__get_change_manipulator))
|
||||
|
||||
|
||||
|
||||
def __get_FIELD_display(self, field):
|
||||
value = getattr(self, field.attname)
|
||||
return dict(field.choices).get(value, value)
|
||||
@ -1259,6 +1270,8 @@ class Model(object):
|
||||
connection.commit()
|
||||
|
||||
|
||||
|
||||
|
||||
############################################
|
||||
# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
|
||||
############################################
|
||||
@ -1503,6 +1516,73 @@ def get_manipulator(opts, klass, extra_methods, add=False, change=False):
|
||||
setattr(man, k, v)
|
||||
return man
|
||||
|
||||
class AutomaticManipulator(formfields.Manipulator):
|
||||
def __classinit__(cls, model):
|
||||
cls.model = model
|
||||
cls.manager = model._default_manager
|
||||
__classinit__ = classmethod(__classinit__)
|
||||
|
||||
def __init__(self, follow=None):
|
||||
self.follow = self.model._meta.get_follow(follow)
|
||||
self.fields = []
|
||||
|
||||
for f in opts.fields + opts.many_to_many:
|
||||
if self.follow.get(f.name, False):
|
||||
self.fields.extend(f.get_manipulator_fields(opts, self, change))
|
||||
|
||||
# Add fields for related objects.
|
||||
for f in opts.get_all_related_objects():
|
||||
if self.follow.get(f.name, False):
|
||||
fol = self.follow[f.name]
|
||||
self.fields.extend(f.get_manipulator_fields(opts, self, change, fol))
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
|
||||
def get_related_objects(opts, klass, add, change, self):
|
||||
return opts.get_followed_related_objects(self.follow)
|
||||
|
||||
def flatten_data(opts, klass, add, change, self):
|
||||
new_data = {}
|
||||
obj = change and self.original_object or None
|
||||
for f in opts.get_data_holders(self.follow):
|
||||
fol = self.follow.get(f.name)
|
||||
new_data.update(f.flatten_data(fol, obj))
|
||||
return new_data
|
||||
|
||||
class ModelAddManipulator(AutomaticManipulator):
|
||||
pass
|
||||
|
||||
class ModelSaveManipulator(AutomaticManipulator):
|
||||
def __init__(self, obj_key=None, follow=None):
|
||||
|
||||
assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter."
|
||||
self.obj_key = obj_key
|
||||
try:
|
||||
self.original_object = self.manager.get_object(pk=obj_key)
|
||||
except ObjectDoesNotExist:
|
||||
# If the object doesn't exist, this might be a manipulator for a
|
||||
# one-to-one related object that hasn't created its subobject yet.
|
||||
# For example, this might be a Restaurant for a Place that doesn't
|
||||
# yet have restaurant information.
|
||||
if opts.one_to_one_field:
|
||||
# Sanity check -- Make sure the "parent" object exists.
|
||||
# For example, make sure the Place exists for the Restaurant.
|
||||
# Let the ObjectDoesNotExist exception propogate up.
|
||||
lookup_kwargs = opts.one_to_one_field.rel.limit_choices_to
|
||||
lookup_kwargs['%s__exact' % opts.one_to_one_field.rel.field_name] = obj_key
|
||||
_ = opts.one_to_one_field.rel.to._meta.get_model_module().get_object(**lookup_kwargs)
|
||||
params = dict([(f.attname, f.get_default()) for f in opts.fields])
|
||||
params[opts.pk.attname] = obj_key
|
||||
self.original_object = opts.get_model_module().Klass(**params)
|
||||
else:
|
||||
raise
|
||||
|
||||
super(ModelSaveManipulator, self).__init__(self, follow=follow)
|
||||
|
||||
if opts.get_ordered_objects():
|
||||
self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_"))
|
||||
|
||||
def manipulator_init(opts, add, change, self, obj_key=None, follow=None):
|
||||
self.follow = opts.get_follow(follow)
|
||||
|
||||
@ -1691,16 +1771,7 @@ def manipulator_save(opts, klass, add, change, self, new_data):
|
||||
getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order)
|
||||
return new_object
|
||||
|
||||
def manipulator_get_related_objects(opts, klass, add, change, self):
|
||||
return opts.get_followed_related_objects(self.follow)
|
||||
|
||||
def manipulator_flatten_data(opts, klass, add, change, self):
|
||||
new_data = {}
|
||||
obj = change and self.original_object or None
|
||||
for f in opts.get_data_holders(self.follow):
|
||||
fol = self.follow.get(f.name)
|
||||
new_data.update(f.flatten_data(fol, obj))
|
||||
return new_data
|
||||
|
||||
def manipulator_validator_unique_together(field_name_list, opts, self, field_data, all_data):
|
||||
from django.utils.text import get_text_list
|
||||
|
Loading…
x
Reference in New Issue
Block a user