Package django :: Package contrib :: Package admin :: Package templatetags :: Module admin_modify
[hide private]
[frames] | no frames]

Source Code for Module django.contrib.admin.templatetags.admin_modify

  1  from django import template 
  2  from django.contrib.admin.views.main import AdminBoundField 
  3  from django.template import loader 
  4  from django.utils.text import capfirst 
  5  from django.utils.encoding import force_unicode 
  6  from django.utils.safestring import mark_safe 
  7  from django.utils.html import escape 
  8  from django.db import models 
  9  from django.db.models.fields import Field 
 10  from django.db.models.related import BoundRelatedObject 
 11  from django.conf import settings 
 12  import re 
 13   
 14  register = template.Library() 
 15   
 16  word_re = re.compile('[A-Z][a-z]+') 
 17  absolute_url_re = re.compile(r'^(?:http(?:s)?:/)?/', re.IGNORECASE) 
 18   
19 -def class_name_to_underscored(name):
20 return u'_'.join([s.lower() for s in word_re.findall(name)[:-1]])
21
22 -def include_admin_script(script_path):
23 """ 24 Returns an HTML script element for including a script from the admin 25 media url (or other location if an absolute url is given). 26 27 Example usage:: 28 29 {% include_admin_script "js/calendar.js" %} 30 31 could return:: 32 33 <script type="text/javascript" src="/media/admin/js/calendar.js"> 34 """ 35 if not absolute_url_re.match(script_path): 36 script_path = '%s%s' % (settings.ADMIN_MEDIA_PREFIX, script_path) 37 return mark_safe(u'<script type="text/javascript" src="%s"></script>' 38 % script_path)
39 include_admin_script = register.simple_tag(include_admin_script) 40
41 -def submit_row(context):
42 opts = context['opts'] 43 change = context['change'] 44 is_popup = context['is_popup'] 45 return { 46 'onclick_attrib': (opts.get_ordered_objects() and change 47 and 'onclick="submitOrderForm();"' or ''), 48 'show_delete_link': (not is_popup and context['has_delete_permission'] 49 and (change or context['show_delete'])), 50 'show_save_as_new': not is_popup and change and opts.admin.save_as, 51 'show_save_and_add_another': not is_popup and (not opts.admin.save_as or context['add']), 52 'show_save_and_continue': not is_popup and context['has_change_permission'], 53 'show_save': True 54 }
55 submit_row = register.inclusion_tag('admin/submit_line.html', takes_context=True)(submit_row) 56
57 -def field_label(bound_field):
58 class_names = [] 59 if isinstance(bound_field.field, models.BooleanField): 60 class_names.append("vCheckboxLabel") 61 colon = "" 62 else: 63 if not bound_field.field.blank: 64 class_names.append('required') 65 if not bound_field.first: 66 class_names.append('inline') 67 colon = ":" 68 class_str = class_names and u' class="%s"' % u' '.join(class_names) or u'' 69 return mark_safe(u'<label for="%s"%s>%s%s</label> ' % 70 (bound_field.element_id, class_str, 71 escape(force_unicode(capfirst(bound_field.field.verbose_name))), 72 colon))
73 field_label = register.simple_tag(field_label) 74
75 -class FieldWidgetNode(template.Node):
76 nodelists = {} 77 default = None 78
79 - def __init__(self, bound_field_var):
80 self.bound_field_var = template.Variable(bound_field_var)
81
82 - def get_nodelist(cls, klass):
83 if klass not in cls.nodelists: 84 try: 85 field_class_name = klass.__name__ 86 template_name = u"widget/%s.html" % class_name_to_underscored(field_class_name) 87 nodelist = loader.get_template(template_name).nodelist 88 except template.TemplateDoesNotExist: 89 super_klass = bool(klass.__bases__) and klass.__bases__[0] or None 90 if super_klass and super_klass != Field: 91 nodelist = cls.get_nodelist(super_klass) 92 else: 93 if not cls.default: 94 cls.default = loader.get_template("widget/default.html").nodelist 95 nodelist = cls.default 96 97 cls.nodelists[klass] = nodelist 98 return nodelist 99 else: 100 return cls.nodelists[klass]
101 get_nodelist = classmethod(get_nodelist) 102
103 - def render(self, context):
104 bound_field = self.bound_field_var.resolve(context) 105 106 context.push() 107 context['bound_field'] = bound_field 108 109 output = self.get_nodelist(bound_field.field.__class__).render(context) 110 context.pop() 111 return output
112
113 -class FieldWrapper(object):
114 - def __init__(self, field ):
115 self.field = field
116
117 - def needs_header(self):
118 return not isinstance(self.field, models.AutoField)
119
120 - def header_class_attribute(self):
121 return self.field.blank and mark_safe(' class="optional"') or ''
122
123 - def use_raw_id_admin(self):
124 return isinstance(self.field.rel, (models.ManyToOneRel, models.ManyToManyRel)) \ 125 and self.field.rel.raw_id_admin
126
127 -class FormFieldCollectionWrapper(object):
128 - def __init__(self, field_mapping, fields, index):
129 self.field_mapping = field_mapping 130 self.fields = fields 131 self.bound_fields = [AdminBoundField(field, self.field_mapping, field_mapping['original']) 132 for field in self.fields] 133 self.index = index
134
135 -class TabularBoundRelatedObject(BoundRelatedObject):
136 - def __init__(self, related_object, field_mapping, original):
137 super(TabularBoundRelatedObject, self).__init__(related_object, field_mapping, original) 138 self.field_wrapper_list = [FieldWrapper(field) for field in self.relation.editable_fields()] 139 140 fields = self.relation.editable_fields() 141 142 self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping, fields, i) 143 for (i,field_mapping) in self.field_mappings.items() ] 144 self.original_row_needed = max([fw.use_raw_id_admin() for fw in self.field_wrapper_list]) 145 self.show_url = original and hasattr(self.relation.opts, 'get_absolute_url')
146
147 - def template_name(self):
148 return "admin/edit_inline_tabular.html"
149
150 -class StackedBoundRelatedObject(BoundRelatedObject):
151 - def __init__(self, related_object, field_mapping, original):
152 super(StackedBoundRelatedObject, self).__init__(related_object, field_mapping, original) 153 fields = self.relation.editable_fields() 154 self.field_mappings.fill() 155 self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping ,fields, i) 156 for (i,field_mapping) in self.field_mappings.items()] 157 self.show_url = original and hasattr(self.relation.opts, 'get_absolute_url')
158
159 - def template_name(self):
160 return "admin/edit_inline_stacked.html"
161
162 -class EditInlineNode(template.Node):
163 - def __init__(self, rel_var):
164 self.rel_var = template.Variable(rel_var)
165
166 - def render(self, context):
167 relation = self.rel_var.resolve(context) 168 context.push() 169 if relation.field.rel.edit_inline == models.TABULAR: 170 bound_related_object_class = TabularBoundRelatedObject 171 elif relation.field.rel.edit_inline == models.STACKED: 172 bound_related_object_class = StackedBoundRelatedObject 173 else: 174 bound_related_object_class = relation.field.rel.edit_inline 175 original = context.get('original', None) 176 bound_related_object = relation.bind(context['form'], original, bound_related_object_class) 177 context['bound_related_object'] = bound_related_object 178 t = loader.get_template(bound_related_object.template_name()) 179 output = t.render(context) 180 context.pop() 181 return output
182
183 -def output_all(form_fields):
184 return u''.join([force_unicode(f) for f in form_fields])
185 output_all = register.simple_tag(output_all) 186
187 -def auto_populated_field_script(auto_pop_fields, change = False):
188 t = [] 189 for field in auto_pop_fields: 190 if change: 191 t.append(u'document.getElementById("id_%s")._changed = true;' % field.name) 192 else: 193 t.append(u'document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name) 194 195 add_values = u' + " " + '.join([u'document.getElementById("id_%s").value' % g for g in field.prepopulate_from]) 196 for f in field.prepopulate_from: 197 t.append(u'document.getElementById("id_%s").onkeyup = function() {' \ 198 ' var e = document.getElementById("id_%s");' \ 199 ' if(!e._changed) { e.value = URLify(%s, %s);} }; ' % ( 200 f, field.name, add_values, field.max_length)) 201 return mark_safe(u''.join(t))
202 auto_populated_field_script = register.simple_tag(auto_populated_field_script) 203
204 -def filter_interface_script_maybe(bound_field):
205 f = bound_field.field 206 if f.rel and isinstance(f.rel, models.ManyToManyRel) and f.rel.filter_interface: 207 return mark_safe(u'<script type="text/javascript">addEvent(window, "load", function(e) {' \ 208 ' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % ( 209 f.name, escape(f.verbose_name.replace('"', '\\"')), f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)) 210 else: 211 return ''
212 filter_interface_script_maybe = register.simple_tag(filter_interface_script_maybe) 213
214 -def field_widget(parser, token):
215 bits = token.contents.split() 216 if len(bits) != 2: 217 raise template.TemplateSyntaxError, "%s takes 1 argument" % bits[0] 218 return FieldWidgetNode(bits[1])
219 field_widget = register.tag(field_widget) 220
221 -def edit_inline(parser, token):
222 bits = token.contents.split() 223 if len(bits) != 2: 224 raise template.TemplateSyntaxError, "%s takes 1 argument" % bits[0] 225 return EditInlineNode(bits[1])
226 edit_inline = register.tag(edit_inline) 227
228 -def admin_field_line(context, argument_val):
229 if isinstance(argument_val, AdminBoundField): 230 bound_fields = [argument_val] 231 else: 232 bound_fields = [bf for bf in argument_val] 233 add = context['add'] 234 change = context['change'] 235 236 class_names = ['form-row'] 237 for bound_field in bound_fields: 238 for f in bound_field.form_fields: 239 if f.errors(): 240 class_names.append('errors') 241 break 242 243 # Assumes BooleanFields won't be stacked next to each other! 244 if isinstance(bound_fields[0].field, models.BooleanField): 245 class_names.append('checkbox-row') 246 247 return { 248 'add': context['add'], 249 'change': context['change'], 250 'bound_fields': bound_fields, 251 'class_names': " ".join(class_names), 252 }
253 admin_field_line = register.inclusion_tag('admin/field_line.html', takes_context=True)(admin_field_line) 254