Ticket #10590: nested_fieldsets.diff
File nested_fieldsets.diff, 9.0 KB (added by , 16 years ago) |
---|
-
django/contrib/admin/helpers.py
41 41 media = property(_media) 42 42 43 43 class Fieldset(object): 44 def __init__(self, form, name=None, fields=(), classes=(), description=None): 44 is_fieldset = True 45 def __init__(self, form, name=None, fields=(), classes=(), description=None, level=0): 45 46 self.form = form 46 47 self.name, self.fields = name, fields 47 48 self.classes = u' '.join(classes) 48 49 self.description = description 50 self.level = level 49 51 50 52 def _media(self): 51 53 if 'collapse' in self.classes: … … 55 57 56 58 def __iter__(self): 57 59 for field in self.fields: 58 yield Fieldline(self.form, field) 60 if (len(field)==2 and isinstance(field[1], dict)): 61 # nested fieldset 62 yield Fieldset(self.form, 63 name=field[0], 64 fields=field[1].get("fields", ()), 65 classes=field[1].get("classes", ()), 66 description=field[1].get("description", ()), 67 level=self.level + 1, 68 ) 69 else: 70 # field name or a tuple of field names 71 yield Fieldline(self.form, field) 59 72 60 73 class Fieldline(object): 61 74 def __init__(self, form, field): … … 175 188 for field in self.fields: 176 189 if fk and fk.name == field: 177 190 continue 178 yield Fieldline(self.form, field) 191 if (len(field)==2 and isinstance(field[1], dict)): 192 # nested fieldset 193 yield Fieldset(self.form, 194 name=field[0], 195 fields=field[1].get("fields", ()), 196 classes=field[1].get("classes", ()), 197 description=field[1].get("description", ()), 198 level=self.level + 1, 199 ) 200 else: 201 # field name or a tuple of field names 202 yield Fieldline(self.form, field) 179 203 180 204 class AdminErrorList(forms.util.ErrorList): 181 205 """ -
django/contrib/admin/media/css/forms.css
123 123 width: 450px; 124 124 } 125 125 126 /* NESTED FIELDSETS */ 127 128 fieldset fieldset { 129 margin: 10px; 130 } 131 126 132 /* COLLAPSED FIELDSETS */ 127 133 128 134 fieldset.collapsed * { -
django/contrib/admin/templates/admin/includes/fieldset.html
1 1 <fieldset class="module aligned {{ fieldset.classes }}"> 2 {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %} 3 {% if fieldset.description %}<div class="description">{{ fieldset.description|safe }}</div>{% endif %} 4 {% for line in fieldset %} 5 <div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} "> 6 {{ line.errors }} 7 {% for field in line %} 8 <div{% if not line.fields|length_is:"1" %} class="field-box"{% endif %}> 9 {% if field.is_checkbox %} 10 {{ field.field }}{{ field.label_tag }} 11 {% else %} 12 {{ field.label_tag }}{{ field.field }} 13 {% endif %} 14 {% if field.field.field.help_text %}<p class="help">{{ field.field.field.help_text|safe }}</p>{% endif %} 15 </div> 16 {% endfor %} 17 </div> 18 {% endfor %} 2 {% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %} 3 {% if fieldset.description %}<div class="description">{{ fieldset.description|safe }}</div>{% endif %} 4 {% for line in fieldset %} 5 {% if line.is_fieldset %} 6 {% include_parsed "admin/includes/fieldset.html" with line as fieldset %} 7 {% else %} 8 <div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} "> 9 {{ line.errors }} 10 {% for field in line %} 11 <div{% if not line.fields|length_is:"1" %} class="field-box"{% endif %}> 12 {% if field.is_checkbox %} 13 {{ field.field }}{{ field.label_tag }} 14 {% else %} 15 {{ field.label_tag }}{{ field.field }} 16 {% endif %} 17 {% if field.field.field.help_text %}<p class="help">{{ field.field.field.help_text|safe }}</p>{% endif %} 18 </div> 19 {% endfor %} 20 </div> 21 {% endif %} 22 {% endfor %} 19 23 </fieldset> -
django/contrib/admin/util.py
47 47 field_names = [] 48 48 for name, opts in fieldsets: 49 49 for field in opts['fields']: 50 # type checking feels dirty, but it seems like the best way here 51 if type(field) == tuple: 52 field_names.extend(field) 50 if isinstance(field, (tuple, list)): 51 if len(field)==2 and isinstance(field[1], dict): 52 # it's a nested fieldset 53 field_names.extend(flatten_fieldsets((field,))) 54 else: 55 # it's a tuple of field names 56 field_names.extend(field) 53 57 else: 58 # it's a field name 54 59 field_names.append(field) 55 60 return field_names 56 61 -
django/template/defaulttags.py
8 8 except NameError: 9 9 from django.utils.itercompat import reversed # Python 2.3 fallback 10 10 11 from django.template import loader, RequestContext, Template 11 12 from django.template import Node, NodeList, Template, Context, Variable 12 13 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END 13 14 from django.template import get_library, Library, InvalidTemplateLibrary … … 432 433 context.pop() 433 434 return output 434 435 436 class ParsedIncludeNode(Node): 437 def __init__(self, tag_name, template_path, extra): 438 self.tag_name = tag_name 439 self.template_path = template_path 440 self.extra = extra 441 def render(self, context): 442 template_path = self.template_path.resolve(context) 443 context_vars = {} 444 for d in list(context): 445 for var, val in d.items(): 446 context_vars[var] = val 447 for var, val in self.extra: 448 context_vars[var] = val.resolve(context) 449 return loader.render_to_string(template_path, context_vars) 450 435 451 #@register.tag 436 452 def autoescape(parser, token): 437 453 """ … … 1171 1187 parser.delete_first_token() 1172 1188 return WithNode(var, name, nodelist) 1173 1189 do_with = register.tag('with', do_with) 1190 1191 #@register.tag 1192 def do_include_parsed(parser, token): 1193 """ 1194 Parses the defined template with the current context variables and also the ones passed to the template tag. The included template might extend some other template. 1195 1196 Usage:: 1197 1198 {% include_parsed <template_path> [with <value1> as <variable1>[ and <value2> as <variable2>[ and ...]] %} 1199 1200 Examples:: 1201 1202 {% include_parsed "people/item_person.html" %} 1203 {% include_parsed path with membership.user.get_profile as person and membership.persongroup as persongroup %} 1204 1205 """ 1206 bits = token.split_contents() 1207 tag_name = bits.pop(0) 1208 try: 1209 template_path = bits.pop(0) 1210 extra = [] # a tuple of variables names and values to parse before passing to the template 1211 if bits: 1212 bits.pop(0) # remove the word "with" 1213 while bits: 1214 val = bits.pop(0) 1215 bits.pop(0) # remove the word "as" 1216 var = bits.pop(0) 1217 extra.append((var, parser.compile_filter(val))) 1218 if bits: 1219 bits.pop(0) # remove the word "and" 1220 1221 except ValueError: 1222 raise template.TemplateSyntaxError, "include_parsed tag requires a following syntax: {% include_parsed <template_path> [with <value1> as <variable1>[ and <value2> as <variable2>[ and ...]] %}" 1223 return ParsedIncludeNode(parser.compile_filter(tag_name), parser.compile_filter(template_path), extra) 1224 1225 do_include_parsed = register.tag('include_parsed', do_include_parsed) 1226