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

Small template debugging fixes. Filter specs now have totally template driven output

git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@1128 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Robert Wittams 2005-11-08 21:46:21 +00:00
parent fd871041bb
commit 24cdaa77fa
6 changed files with 93 additions and 67 deletions

View File

@ -0,0 +1,7 @@
<h3>{%blocktrans%} By {{title}} {%endblocktrans%}</h3>
<ul>
{% for choice in choices %}
<li{%if choice.selected%} class="selected"{%endif%}>
<a href="{{choice.query_string}}">{{choice.display}}</a></li>
{% endfor %}
</ul>

View File

@ -1,5 +1,5 @@
{% if cl.has_filters %}<div id="changelist-filter"> {% if cl.has_filters %}<div id="changelist-filter">
<h2>Filter</h2> <h2>Filter</h2>
{% for spec in cl.filter_specs %} {% for spec in cl.filter_specs %}
{% output_filter_spec cl spec %} {% filter cl spec %}
{% endfor %}</div>{% endif %} {% endfor %}</div>{% endif %}

View File

@ -4,8 +4,8 @@
<div> <div>
<h2> Error in Template </h2> <h2> Error in Template </h2>
<pre> <pre>
{{message}} {{message|escape}}
{{traceback}} {{traceback|escape}}
</pre> </pre>
{%if top%} {%if top%}

View File

@ -209,8 +209,6 @@ def items_for_result(cl, result):
else: else:
yield ('<td%s>%s</td>' % (row_class, result_repr)) yield ('<td%s>%s</td>' % (row_class, result_repr))
def results(cl): def results(cl):
for res in cl.result_list: for res in cl.result_list:
yield list(items_for_result(cl,res)) yield list(items_for_result(cl,res))
@ -224,7 +222,6 @@ def result_list(cl):
result_list = inclusion_tag("admin/change_list_results")(result_list) result_list = inclusion_tag("admin/change_list_results")(result_list)
#@simple_tag #@simple_tag
def date_hierarchy(cl): def date_hierarchy(cl):
lookup_opts, params, lookup_params, lookup_mod = \ lookup_opts, params, lookup_params, lookup_mod = \
@ -278,10 +275,11 @@ def search_form(cl):
'search_var': SEARCH_VAR } 'search_var': SEARCH_VAR }
search_form = inclusion_tag('admin/search_form')(search_form) search_form = inclusion_tag('admin/search_form')(search_form)
#@simple_tag #@inclusion_tag('admin/filter')
def output_filter_spec(cl, spec): def filter(cl, spec):
return spec.output(cl) return {'title': spec.title(),
output_filter_spec = simple_tag(output_filter_spec) 'choices' : list(spec.choices(cl))}
filter = inclusion_tag('admin/filter')(filter)
#@inclusion_tag('admin/filters') #@inclusion_tag('admin/filters')
def filters(cl): def filters(cl):

View File

@ -72,21 +72,26 @@ class FilterSpec(object):
def has_output(self): def has_output(self):
return True return True
def choices(self, cl):
raise NotImplementedException()
def title(self):
return self.field.verbose_name
def output(self, cl): def output(self, cl):
t = [] t = []
if self.has_output(): if self.has_output():
t.append(_('<h3>By %s:</h3>\n<ul>\n') % self.title) t.append(_('<h3>By %s:</h3>\n<ul>\n') % self.title())
for choice in self.choices: for choice in self.choices(cl):
t.append('<li%s><a href="%s">%s</a></li>\n' % \ t.append('<li%s><a href="%s">%s</a></li>\n' % \
(self.is_selected(choice) and ' class="selected"' or ''), ((choice['selected'] and ' class="selected"' or ''),
self.get_query_string(choice) , choice['query_string'] ,
self.get_display(choice) ) choice['display']))
t.append('</ul>\n\n') t.append('</ul>\n\n')
return "".join(t) return "".join(t)
class RelatedFilterSpec(FilterSpec): class RelatedFilterSpec(FilterSpec):
def __init__(self, f, request, params): def __init__(self, f, request, params):
super(RelatedFilterSpec, self).__init__(f, request, params) super(RelatedFilterSpec, self).__init__(f, request, params)
if isinstance(f, meta.ManyToManyField): if isinstance(f, meta.ManyToManyField):
@ -100,20 +105,18 @@ class RelatedFilterSpec(FilterSpec):
def has_output(self): def has_output(self):
return len(self.lookup_choices) > 1 return len(self.lookup_choices) > 1
def output(self, cl): def title(self):
t = [] return self.lookup_title
if self.has_output():
t.append(_('<h3>By %s:</h3>\n<ul>\n') % self.lookup_title) def choices(self, cl):
t.append('<li%s><a href="%s">All</a></li>\n' % \ yield {'selected': self.lookup_val is None,
((self.lookup_val is None and ' class="selected"' or ''), 'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
cl.get_query_string({}, [self.lookup_kwarg]))) 'display': _('All') }
for val in self.lookup_choices: for val in self.lookup_choices:
pk_val = getattr(val, self.field.rel.to.pk.column) pk_val = getattr(val, self.field.rel.to.pk.column)
t.append('<li%s><a href="%s">%s</a></li>\n' % \ yield { 'selected': self.lookup_val == str(pk_val),
((self.lookup_val == str(pk_val) and ' class="selected"' or ''), 'query_string': cl.get_query_string( {self.lookup_kwarg: pk_val}),
cl.get_query_string( {self.lookup_kwarg: pk_val}), val)) 'display' : val }
t.append('</ul>\n\n')
return "".join(t)
FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
class ChoicesFilterSpec(FilterSpec): class ChoicesFilterSpec(FilterSpec):
@ -123,18 +126,14 @@ class ChoicesFilterSpec(FilterSpec):
self.lookup_kwarg = '%s__exact' % f.name self.lookup_kwarg = '%s__exact' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None) self.lookup_val = request.GET.get(self.lookup_kwarg, None)
def output(self, cl): def choices(self, cl):
t = [] yield {'selected' : self.lookup_val is None,
t.append(_('<h3>By %s:</h3><ul>\n') % self.field.verbose_name) 'query_string': cl.get_query_string( {}, [self.lookup_kwarg]),
t.append('<li%s><a href="%s">All</a></li>\n' % \ 'display': _('All') }
((self.lookup_val is None and ' class="selected"' or ''),
cl.get_query_string( {}, [self.lookup_kwarg])))
for k, v in self.field.choices: for k, v in self.field.choices:
t.append('<li%s><a href="%s">%s</a></li>' % \ yield {'selected': str(k) == self.lookup_val,
((str(k) == self.lookup_val) and ' class="selected"' or '', 'query_string' : cl.get_query_string( {self.lookup_kwarg: k}),
cl.get_query_string( {self.lookup_kwarg: k}), v)) 'display' : v }
t.append('</ul>\n\n')
return "".join(t)
FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
class DateFieldFilterSpec(FilterSpec): class DateFieldFilterSpec(FilterSpec):
@ -161,16 +160,16 @@ class DateFieldFilterSpec(FilterSpec):
'%s__month' % f.name: str(today.month)}), '%s__month' % f.name: str(today.month)}),
('This year', {'%s__year' % self.field.name: str(today.year)}) ('This year', {'%s__year' % self.field.name: str(today.year)})
) )
def output(self, cl): def title(self):
t = [] return self.field.verbose_name
t.append(_('<h3>By %s:</h3><ul>\n') % self.field.verbose_name)
def choices(self, cl):
for title, param_dict in self.links: for title, param_dict in self.links:
t.append('<li%s><a href="%s">%s</a></li>\n' % \ yield { 'selected' : self.date_params == param_dict,
((self.date_params == param_dict) and ' class="selected"' or '', 'query_string' : cl.get_query_string( param_dict, self.field_generic),
cl.get_query_string( param_dict, self.field_generic), title)) 'display' : title }
t.append('</ul>\n\n')
return "".join(t)
FilterSpec.register(lambda f: isinstance(f, meta.DateField), DateFieldFilterSpec) FilterSpec.register(lambda f: isinstance(f, meta.DateField), DateFieldFilterSpec)
class BooleanFieldFilterSpec(FilterSpec): class BooleanFieldFilterSpec(FilterSpec):
@ -182,19 +181,20 @@ class BooleanFieldFilterSpec(FilterSpec):
self.lookup_val = request.GET.get(self.lookup_kwarg, None) self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None)
def output(self, cl): def title(self):
t = [] return self.field.verbose_name
t.append(_('<h3>By %s:</h3><ul>\n') % self.field.verbose_name)
def choices(self, cl):
for k, v in (('All', None), ('Yes', '1'), ('No', '0')): for k, v in (('All', None), ('Yes', '1'), ('No', '0')):
t.append('<li%s><a href="%s">%s</a></li>\n' % \ yield { 'selected' : self.lookup_val == v and not self.lookup_val2,
(((self.lookup_val == v and not self.lookup_val2) and ' class="selected"' or ''), 'query_string' : cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg2]),
cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg2]), k)) 'display': k
}
if isinstance(self.field, meta.NullBooleanField): if isinstance(self.field, meta.NullBooleanField):
t.append('<li%s><a href="%s">%s</a></li>\n' % \ yield { 'selected' : lookup_val2 == 'True',
(((lookup_val2 == 'True') and ' class="selected"' or ''), 'query_string' : cl.get_query_string( {self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]),
cl.get_query_string( {self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]), 'Unknown')) 'display': _('Unknown')
t.append('</ul>\n\n') }
return "".join(t)
FilterSpec.register(lambda f: isinstance(f, meta.BooleanField) or FilterSpec.register(lambda f: isinstance(f, meta.BooleanField) or
isinstance(f, meta.NullBooleanField), BooleanFieldFilterSpec) isinstance(f, meta.NullBooleanField), BooleanFieldFilterSpec)

View File

@ -286,7 +286,8 @@ class Parser(object):
elif token.token_type == TOKEN_VAR: elif token.token_type == TOKEN_VAR:
if not token.contents: if not token.contents:
self.empty_variable(token) self.empty_variable(token)
self.extend_nodelist(nodelist, VariableNode(token.contents), token) var_node = self.create_variable_node(token.contents)
self.extend_nodelist(nodelist, var_node,token)
elif token.token_type == TOKEN_BLOCK: elif token.token_type == TOKEN_BLOCK:
if token.contents in parse_until: if token.contents in parse_until:
# put token back on token list so calling code knows why it terminated # put token back on token list so calling code knows why it terminated
@ -313,6 +314,9 @@ class Parser(object):
self.unclosed_block_tag(token, parse_until) self.unclosed_block_tag(token, parse_until)
return nodelist return nodelist
def create_variable_node(self, contents):
return VariableNode(contents)
def create_nodelist(self): def create_nodelist(self):
return NodeList() return NodeList()
@ -374,6 +378,9 @@ class DebugParser(Parser):
def create_nodelist(self): def create_nodelist(self):
return DebugNodeList() return DebugNodeList()
def create_variable_node(self, contents):
return DebugVariableNode(contents)
def extend_nodelist(self, nodelist, node, token): def extend_nodelist(self, nodelist, node, token):
node.source = token.source node.source = token.source
super(DebugParser, self).extend_nodelist(nodelist, node, token) super(DebugParser, self).extend_nodelist(nodelist, node, token)
@ -866,14 +873,28 @@ class VariableNode(Node):
def __repr__(self): def __repr__(self):
return "<Variable Node: %s>" % self.var_string return "<Variable Node: %s>" % self.var_string
def render(self, context): def encode_output(self, output):
output = resolve_variable_with_filters(self.var_string, context)
# Check type so that we don't run str() on a Unicode object # Check type so that we don't run str() on a Unicode object
if not isinstance(output, basestring): if not isinstance(output, basestring):
output = str(output) return str(output)
elif isinstance(output, unicode): elif isinstance(output, unicode):
output = output.encode(DEFAULT_CHARSET) return output.encode(DEFAULT_CHARSET)
return output else:
return output
def render(self, context):
output = resolve_variable_with_filters(self.var_string, context)
return self.encode_output(output)
class DebugVariableNode(VariableNode):
def render(self, context):
try:
output = resolve_variable_with_filters(self.var_string, context)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = self.source
raise
return self.encode_output(output)
def register_tag(token_command, callback_function): def register_tag(token_command, callback_function):
registered_tags[token_command] = callback_function registered_tags[token_command] = callback_function