mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Fixed token parsing bug in the error stuff.
Reorganisation and rationalisation of helper objects for admin templates. git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@802 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -50,14 +50,14 @@
|
||||
{% endif %}
|
||||
<b>
|
||||
</b>
|
||||
{% for fieldset in admin_fieldsets %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% if fieldset.name %}
|
||||
<h2>{{fieldset.name }}</h2>
|
||||
{% for bound_field_set in bound_field_sets %}
|
||||
<fieldset class="module aligned {{ bound_field_set.classes }}">
|
||||
{% if bound_field_set.name %}
|
||||
<h2>{{bound_field_set.name }}</h2>
|
||||
{% endif %}
|
||||
{% for bound_field_set in fieldset.bound_field_sets %}
|
||||
{% for bound_field in bound_field_set %}
|
||||
{% admin_field_bound bound_field %}
|
||||
{% for bound_field_line in bound_field_set %}
|
||||
{% admin_field_line bound_field_line %}
|
||||
{% for bound_field in bound_field_line %}
|
||||
{% filter_interface_script_maybe bound_field %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{% if bound_field.not_in_table %}
|
||||
{% field_widget bound_field %}
|
||||
{% else %}
|
||||
{% admin_field_bound bound_field %}
|
||||
{% admin_field_line bound_field %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{%endfor%}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="{{ class_names }}">
|
||||
<div class="{{ class_names }}" >
|
||||
{% for bound_field in bound_fields %}
|
||||
{{ bound_field.html_error_list }}
|
||||
{% endfor %}
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
{% if change %}
|
||||
{% if bound_field.field.primary_key %}
|
||||
{{ bound_field.original_value }}
|
||||
{% endif %}
|
||||
{{ bound_field.original_value }}
|
||||
{% endif %}
|
||||
|
||||
{% if bound_field.raw_id_admin %}
|
||||
{% if bound_field.existing_repr %}
|
||||
@@ -31,6 +31,6 @@
|
||||
{{bound_field.field.help_text}}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
{% if bound_field.is_date_time %}
|
||||
<p class="datetime">
|
||||
Date: {{ bound_field.form_fields.0 }}<br />
|
||||
Time: {{ bound_field.form_fields.1 }}
|
||||
</p>
|
||||
{% else %}
|
||||
{% if bound_field.is_file_field %}
|
||||
{% if bound_field.original_value %}
|
||||
Currently: <a href="{{ bound_field.original_url }}" > {{ bound_field.original_value }} </a><br />
|
||||
Change: {% output_all bound_field.form_fields %}
|
||||
{% else %}
|
||||
{% output_all bound_field.form_fields %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% output_all bound_field.form_fields %}
|
||||
{% if bound_field.raw_id_admin %}
|
||||
<a href="../../../{{ bound_field.field.rel.to.app_label }}/{{ bound_field.field.rel.to.module_name }}/" class="related-lookup" id="lookup_{{bound_field.element_id}}" onclick="return showRelatedObjectLookupPopup(this);"> <img src="{% admin_media_prefix %}img/admin/selector-search.gif" width="16" height="16" alt="Lookup"></a>
|
||||
{% else %}
|
||||
{% if bound_field.needs_add_label %}
|
||||
<a href="../../../{{ bound_field.field.rel.to.app_label }}/{{ bound_field.field.rel.to.module_name }}/add/" class="add-another" id="add_{{ bound_field.element_id}}" onclick="return showAddAnotherPopup(this);"> <img src="{% admin_media_prefix %}img/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
@@ -786,6 +786,93 @@ class OneToOne(ManyToOne):
|
||||
self.lookup_overrides = lookup_overrides or {}
|
||||
self.raw_id_admin = raw_id_admin
|
||||
|
||||
|
||||
|
||||
class BoundField(object):
|
||||
def __init__(self, field, field_mapping, original):
|
||||
self.field = field
|
||||
self.form_fields = self.resolve_form_fields(field_mapping)
|
||||
self.original = original
|
||||
|
||||
def resolve_form_fields(self, field_mapping):
|
||||
return [field_mapping[name] for name in self.field.get_manipulator_field_names('')]
|
||||
|
||||
def as_field_list(self):
|
||||
return [self.field]
|
||||
|
||||
def original_value(self):
|
||||
return self.original.__dict__[self.field.name]
|
||||
|
||||
def __repr__(self):
|
||||
return "BoundField:(%s, %s)" %( self.field.name, self.form_fields)
|
||||
|
||||
class BoundFieldLine(object):
|
||||
def __init__(self, field_line, field_mapping, original, bound_field_class=BoundField):
|
||||
self.bound_fields = [bound_field_class(field, field_mapping, original) for field in field_line]
|
||||
|
||||
def __iter__(self):
|
||||
for bound_field in self.bound_fields:
|
||||
yield bound_field
|
||||
|
||||
def __repr__(self):
|
||||
return "%s:(%s)" % (self.__class__.__name__, self.bound_fields)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.bound_fields)
|
||||
|
||||
class FieldLine(object):
|
||||
def __init__(self, linespec, field_locator_func):
|
||||
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=BoundFieldLine):
|
||||
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 BoundFieldSet(object):
|
||||
def __init__(self, field_set, field_mapping, original, bound_field_line_class=BoundFieldLine):
|
||||
self.name = field_set.name
|
||||
self.classes = field_set.classes
|
||||
self.bound_field_lines = [ field_line.bind(field_mapping,original, bound_field_line_class)
|
||||
for field_line in field_set]
|
||||
def __repr__(self):
|
||||
return "%s:(%s,%s)" % (self.__class__.__name__, self.name, self.bound_field_lines)
|
||||
|
||||
def __iter__(self):
|
||||
for bound_field_line in self.bound_field_lines:
|
||||
yield bound_field_line
|
||||
|
||||
def __len__(self):
|
||||
return len(self.bound_field_lines)
|
||||
|
||||
class FieldSet(object):
|
||||
def __init__(self, name, classes, field_lines):
|
||||
self.name = name
|
||||
self.field_lines = field_lines
|
||||
self.classes = classes
|
||||
|
||||
def __repr__(self):
|
||||
return "FieldSet:(%s,%s)" % (self.name, self.field_lines)
|
||||
|
||||
def bind(self, field_mapping, original, bound_field_set_class=BoundFieldSet):
|
||||
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 Admin:
|
||||
def __init__(self, fields=None, js=None, list_display=None, list_filter=None, date_hierarchy=None,
|
||||
save_as=False, ordering=None, search_fields=None, save_on_top=False):
|
||||
@@ -808,7 +895,7 @@ class Admin:
|
||||
the dict has attribs 'fields' and maybe 'classes'.
|
||||
fields is a list of subclasses of Field.
|
||||
|
||||
Return value needs to be encapsulated.
|
||||
TODO:Return value needs to be encapsulated.
|
||||
"""
|
||||
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)]}),)
|
||||
@@ -827,3 +914,23 @@ class Admin:
|
||||
new_fieldset[1]['fields'] = admin_fields
|
||||
new_fieldset_list.append(new_fieldset)
|
||||
return new_fieldset_list
|
||||
|
||||
def get_field_sets(self, opts):
|
||||
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:
|
||||
name = fieldset[0]
|
||||
fs_options = fieldset[1]
|
||||
classes = fs_options.get('classes', None)
|
||||
line_specs = fs_options['fields']
|
||||
field_lines = [FieldLine(line_spec, opts.get_field) for line_spec in line_specs]
|
||||
new_fieldset_list.append(FieldSet(name, classes, field_lines) )
|
||||
return new_fieldset_list
|
||||
|
||||
@@ -113,6 +113,11 @@ class Template:
|
||||
def __init__(self, template_string, filename=UNKNOWN_SOURCE):
|
||||
"Compilation stage"
|
||||
self.nodelist = compile_string(template_string, filename)
|
||||
from pprint import pprint, pformat
|
||||
print "------------------------"
|
||||
print filename
|
||||
pprint(self.nodelist)
|
||||
print "------------------------"
|
||||
|
||||
def __iter__(self):
|
||||
for node in self.nodelist:
|
||||
@@ -213,6 +218,11 @@ def tokenize(template_string, filename):
|
||||
while linebreaks and line != lastline and linebreaks[line] <= upto:
|
||||
line += 1
|
||||
|
||||
last_bit = template_string[upto:]
|
||||
if len(last_bit):
|
||||
token_tups.append( (last_bit, line) )
|
||||
|
||||
|
||||
return [ create_token(tok, (filename, line)) for tok, line in token_tups]
|
||||
|
||||
def create_token(token_string, source):
|
||||
|
||||
@@ -8,6 +8,7 @@ from django.utils.functional import curry
|
||||
from django.core.template_decorators import simple_tag, inclusion_tag
|
||||
|
||||
from django.views.admin.main import AdminBoundField
|
||||
from django.core.meta.fields import BoundField
|
||||
import re
|
||||
|
||||
word_re = re.compile('[A-Z][a-z]+')
|
||||
@@ -24,24 +25,24 @@ include_admin_script = simple_tag(include_admin_script)
|
||||
|
||||
#@inclusion_tag('admin_submit_line', takes_context=True)
|
||||
def submit_row(context):
|
||||
change = context['change']
|
||||
add = context['add']
|
||||
show_delete = context['show_delete']
|
||||
ordered_objects = context['ordered_objects']
|
||||
save_as = context['save_as']
|
||||
has_delete_permission = context['has_delete_permission']
|
||||
is_popup = context['is_popup']
|
||||
change = context['change']
|
||||
add = context['add']
|
||||
show_delete = context['show_delete']
|
||||
ordered_objects = context['ordered_objects']
|
||||
save_as = context['save_as']
|
||||
has_delete_permission = context['has_delete_permission']
|
||||
is_popup = context['is_popup']
|
||||
|
||||
return {
|
||||
'onclick_attrib' : (ordered_objects and change
|
||||
and 'onclick="submitOrderForm();"' or ''),
|
||||
'show_delete_link' : (not is_popup and has_delete_permission
|
||||
and (change or show_delete)),
|
||||
'show_save_as_new' : not is_popup and change and save_as,
|
||||
'show_save_and_add_another': not is_popup and (not save_as or add),
|
||||
'show_save_and_continue': not is_popup,
|
||||
'show_save': True
|
||||
}
|
||||
return {
|
||||
'onclick_attrib' : (ordered_objects and change
|
||||
and 'onclick="submitOrderForm();"' or ''),
|
||||
'show_delete_link' : (not is_popup and has_delete_permission
|
||||
and (change or show_delete)),
|
||||
'show_save_as_new' : not is_popup and change and save_as,
|
||||
'show_save_and_add_another': not is_popup and (not save_as or add),
|
||||
'show_save_and_continue': not is_popup,
|
||||
'show_save': True
|
||||
}
|
||||
|
||||
srdec = inclusion_tag('admin_submit_line', takes_context=True)
|
||||
submit_row = srdec(submit_row)
|
||||
@@ -118,10 +119,10 @@ class FieldWrapper(object):
|
||||
and self.field.rel.raw_id_admin
|
||||
|
||||
class FormFieldCollectionWrapper(object):
|
||||
def __init__(self, obj, fields):
|
||||
self.obj = obj
|
||||
def __init__(self, field_mapping, fields):
|
||||
self.field_mapping = field_mapping
|
||||
self.fields = fields
|
||||
self.bound_fields = [ AdminBoundField(field, obj['original'], True, self.obj) for field in self.fields ]
|
||||
self.bound_fields = [ AdminBoundField(field, self.field_mapping, field_mapping['original']) for field in self.fields ]
|
||||
|
||||
def showurl(self):
|
||||
return False
|
||||
@@ -145,7 +146,6 @@ class EditInlineNode(template.Node):
|
||||
context.pop()
|
||||
return output
|
||||
|
||||
|
||||
def fill_context(self, relation, add, change, context):
|
||||
field_wrapper_list = relation.editable_fields(FieldWrapper)
|
||||
|
||||
@@ -154,13 +154,12 @@ class EditInlineNode(template.Node):
|
||||
form = template.resolve_variable('form', context)
|
||||
form_field_collections = form[relation.opts.module_name]
|
||||
fields = relation.editable_fields()
|
||||
form_field_collection_wrapper_list = [FormFieldCollectionWrapper(o,fields) for o in form_field_collections]
|
||||
form_field_collection_wrapper_list = [FormFieldCollectionWrapper(field_mapping ,fields) for field_mapping in form_field_collections]
|
||||
|
||||
context['field_wrapper_list'] = field_wrapper_list
|
||||
context['form_field_collection_wrapper_list'] = form_field_collection_wrapper_list
|
||||
context['num_headers'] = len(field_wrapper_list)
|
||||
context['original_row_needed'] = max([fw.use_raw_id_admin() for fw in field_wrapper_list])
|
||||
# context['name_prefix'] = "%s." % (var_name,)
|
||||
|
||||
|
||||
#@simple_tag
|
||||
@@ -216,12 +215,12 @@ for node in one_arg_tag_nodes:
|
||||
register_one_arg_tag(node)
|
||||
|
||||
|
||||
#@inclusion_tag('admin_field', takes_context=True)
|
||||
def admin_field_bound(context, argument_val):
|
||||
if (isinstance(argument_val, list)):
|
||||
bound_fields = argument_val
|
||||
else:
|
||||
#@inclusion_tag('admin_field_line', takes_context=True)
|
||||
def admin_field_line(context, argument_val):
|
||||
if (isinstance(argument_val, BoundField)):
|
||||
bound_fields = [argument_val]
|
||||
else:
|
||||
bound_fields = [bf for bf in argument_val]
|
||||
add = context['add']
|
||||
change = context['change']
|
||||
|
||||
@@ -244,7 +243,7 @@ def admin_field_bound(context, argument_val):
|
||||
}
|
||||
|
||||
|
||||
afbdec = inclusion_tag('admin_field', takes_context=True)
|
||||
admin_field_bound = afbdec(admin_field_bound)
|
||||
afbdec = inclusion_tag('admin_field_line', takes_context=True)
|
||||
admin_field_line = afbdec(admin_field_line)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generic admin views, with admin templates created dynamically at runtime.
|
||||
|
||||
from django.core import formfields, meta, template_loader, template
|
||||
from django.core.meta.fields import BoundField, BoundFieldLine, BoundFieldSet
|
||||
from django.core.exceptions import Http404, ObjectDoesNotExist, PermissionDenied
|
||||
from django.core.extensions import DjangoContext as Context
|
||||
from django.core.extensions import get_object_or_404, render_to_response
|
||||
@@ -539,25 +540,10 @@ def get_javascript_imports(opts,auto_populated_fields, ordered_objects, admin_fi
|
||||
break
|
||||
return js
|
||||
|
||||
class BoundField(object):
|
||||
def __init__(self, field, original, rel, field_mapping):
|
||||
self.field = field
|
||||
self.form_fields = self.resolve_form_fields(field_mapping)
|
||||
self.original = original
|
||||
self.rel = rel
|
||||
|
||||
def resolve_form_fields(self, field_mapping):
|
||||
return [field_mapping[name] for name in self.field.get_manipulator_field_names('')]
|
||||
|
||||
def as_field_list(self):
|
||||
return [self.field]
|
||||
|
||||
def original_value(self):
|
||||
return self.original.__dict__[self.field.name]
|
||||
|
||||
class AdminBoundField(BoundField):
|
||||
def __init__(self, field, original, rel, field_mapping):
|
||||
super(AdminBoundField, self).__init__(field,original, rel, field_mapping)
|
||||
def __init__(self, field, field_mapping, original):
|
||||
super(AdminBoundField, self).__init__(field,field_mapping,original)
|
||||
|
||||
self.element_id = self.form_fields[0].get_id()
|
||||
self.has_label_first = not isinstance(self.field, meta.BooleanField)
|
||||
@@ -577,8 +563,6 @@ class AdminBoundField(BoundField):
|
||||
self.cell_class_attribute = ' class="%s" ' % ' '.join(classes)
|
||||
self._repr_filled = False
|
||||
|
||||
|
||||
|
||||
def _fetch_existing_repr(self, func_name):
|
||||
class_dict = self.original.__class__.__dict__
|
||||
func = class_dict.get(func_name)
|
||||
@@ -591,9 +575,9 @@ class AdminBoundField(BoundField):
|
||||
if isinstance(self.field.rel, meta.ManyToOne):
|
||||
func_name = 'get_%s' % self.field.name
|
||||
self._repr = self._fetch_existing_repr(func_name)
|
||||
elif isinstance(self.field.rel, meta.ManyToMany):
|
||||
func_name = 'get_%s_list' % self.field.name
|
||||
self._repr = ",".join(self._fetch_existing_repr(func_name))
|
||||
elif isinstance(self.field.rel, meta.ManyToMany):
|
||||
func_name = 'get_%s_list' % self.field.name
|
||||
self._repr = ",".join(self._fetch_existing_repr(func_name))
|
||||
self._repr_filled = True
|
||||
|
||||
def existing_repr(self):
|
||||
@@ -607,33 +591,24 @@ class AdminBoundField(BoundField):
|
||||
return " ".join([form_field.html_error_list() for form_field in self.form_fields if form_field.errors])
|
||||
|
||||
|
||||
class AdminFieldSet(object):
|
||||
def __init__(self, fieldset_name, options, form, original):
|
||||
self.name = fieldset_name
|
||||
self.options = options
|
||||
self.bound_field_sets = self.get_bound_field_sets(form, original)
|
||||
self.classes = options.get('classes', '')
|
||||
class AdminBoundFieldLine(BoundFieldLine):
|
||||
def __init__(self, field_line, field_mapping, original):
|
||||
super(AdminBoundFieldLine, self).__init__(field_line, field_mapping, original, AdminBoundField)
|
||||
for bound_field in self:
|
||||
bound_field.first = True
|
||||
break
|
||||
|
||||
def __repr__(self):
|
||||
return "Fieldset:(%s,%s)" % (self.name, self.bound_field_sets)
|
||||
class AdminBoundFieldSet(BoundFieldSet):
|
||||
def __init__(self, field_set, field_mapping, original):
|
||||
super(AdminBoundFieldSet, self).__init__(field_set, field_mapping, original, AdminBoundFieldLine)
|
||||
|
||||
def get_bound_field_sets(self, form, original):
|
||||
fields = self.options['fields']
|
||||
bound_field_sets = [ [AdminBoundField(f, original, False, form) for f in field ] for field in fields]
|
||||
for set in bound_field_sets:
|
||||
first = True
|
||||
for bound_field in set:
|
||||
bound_field.first = first
|
||||
first = False
|
||||
|
||||
return bound_field_sets
|
||||
|
||||
def fill_extra_context(opts, app_label, context, add=False, change=False, show_delete=False, form_url=''):
|
||||
admin_field_objs = opts.admin.get_field_objs(opts)
|
||||
ordered_objects = opts.get_ordered_objects()[:]
|
||||
auto_populated_fields = [f for f in opts.fields if f.prepopulate_from]
|
||||
|
||||
javascript_imports = get_javascript_imports(opts,auto_populated_fields, ordered_objects, admin_field_objs);
|
||||
javascript_imports = get_javascript_imports(opts, auto_populated_fields, ordered_objects, admin_field_objs);
|
||||
|
||||
if ordered_objects:
|
||||
coltype = 'colMS'
|
||||
@@ -646,7 +621,9 @@ def fill_extra_context(opts, app_label, context, add=False, change=False, show_d
|
||||
|
||||
form = context['form']
|
||||
original = context['original']
|
||||
admin_fieldsets = [AdminFieldSet(name, options, form, original) for name, options in admin_field_objs]
|
||||
bound_field_sets = [field_set.bind(form, original, AdminBoundFieldSet)
|
||||
for field_set in opts.admin.get_field_sets(opts)]
|
||||
|
||||
inline_related_objects = opts.get_inline_related_objects_wrapped()
|
||||
|
||||
ordered_object_names = ' '.join(['object.%s' % o.pk.name for o in ordered_objects])
|
||||
@@ -654,17 +631,16 @@ def fill_extra_context(opts, app_label, context, add=False, change=False, show_d
|
||||
extra_context = {
|
||||
'add': add,
|
||||
'change': change,
|
||||
'admin_field_objs' : admin_field_objs,
|
||||
'ordered_objects' : ordered_objects,
|
||||
'ordered_object_names' : ordered_object_names,
|
||||
'auto_populated_fields' : auto_populated_fields,
|
||||
'javascript_imports' : javascript_imports,
|
||||
'coltype' : coltype,
|
||||
'has_absolute_url': has_absolute_url,
|
||||
'form_enc_attrib': form_enc_attrib,
|
||||
'form_url' : form_url,
|
||||
'admin_fieldsets' : admin_fieldsets,
|
||||
'bound_field_sets' : bound_field_sets,
|
||||
'inline_related_objects': inline_related_objects,
|
||||
'ordered_object_names' : ordered_object_names,
|
||||
'content_type_id' : opts.get_content_type_id(),
|
||||
'save_on_top' : opts.admin.save_on_top,
|
||||
'verbose_name_plural': opts.verbose_name_plural,
|
||||
|
||||
Reference in New Issue
Block a user