Django

Code

Changeset 966

Show
Ignore:
Timestamp:
10/19/05 19:15:01 (3 years ago)
Author:
rjwittams
Message:

Merged to r960. Nightmare. Removed old view functions in admin.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/new-admin/django/contrib/admin/templates/admin/change_form.html

    r883 r966  
    1 {% extends "base_site" %} 
     1{% extends "admin/base_site" %} 
    22{% load admin_modify %} 
    33{% load adminmedia %} 
     
    2121{% endif %}{% endif %} 
    2222<form {{ form_enc_attrib }} action='{{ form_url }}' method="post"> 
     23 
     24 
    2325{% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %} 
    2426{% if save_on_top %}{% submit_row %}{% endif %} 
     
    2628{% for bound_field_set in bound_field_sets %} 
    2729   <fieldset class="module aligned {{ bound_field_set.classes }}"> 
     30    
    2831    {% if bound_field_set.name %}<h2>{{bound_field_set.name }}</h2>{% endif %} 
    2932    {% for bound_field_line in bound_field_set %} 
  • django/branches/new-admin/django/contrib/admin/templates/admin/template_debug.html

    r953 r966  
    1 {% extends "base_site" %} 
     1{% extends "admin/base_site" %} 
    22 
    33{% block content %} 
  • django/branches/new-admin/django/contrib/admin/templatetags/admin_modify.py

    r933 r966  
    2424 
    2525 
    26 #@inclusion_tag('admin_submit_line', takes_context=True) 
     26#@inclusion_tag('admin/submit_line', takes_context=True) 
    2727def submit_row(context): 
    2828    change = context['change'] 
     
    4545    } 
    4646 
    47 srdec = inclusion_tag('admin_submit_line', takes_context=True) 
     47srdec = inclusion_tag('admin/submit_line', takes_context=True) 
    4848submit_row = srdec(submit_row) 
    4949 
     
    220220 
    221221 
    222 #@inclusion_tag('admin_field_line', takes_context=True) 
     222#@inclusion_tag('admin/field_line', takes_context=True) 
    223223def admin_field_line(context, argument_val): 
    224224    if (isinstance(argument_val, BoundField)): 
     
    248248 
    249249     
    250 afbdec = inclusion_tag('admin_field_line', takes_context=True)     
     250afbdec = inclusion_tag('admin/field_line', takes_context=True)     
    251251admin_field_line = afbdec(admin_field_line) 
    252252 
  • django/branches/new-admin/django/contrib/admin/views/main.py

    r939 r966  
    88from django.core.extensions import DjangoContext as Context 
    99from django.core.extensions import get_object_or_404, render_to_response 
    10 from django.models.auth import log 
     10from django.models.admin import log 
    1111from django.utils.html import strip_tags 
    1212from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect 
     
    5151 
    5252def index(request): 
    53     return render_to_response('index', {'title': 'Site administration'}, context_instance=Context(request)) 
     53    return render_to_response('admin/index', {'title': 'Site administration'}, context_instance=Context(request)) 
    5454index = staff_member_required(index) 
    5555 
     
    268268                pass # Invalid argument to "list_filter" 
    269269 
    270     raw_template = ['{% extends "base_site" %}\n'] 
     270    raw_template = ['{% extends "admin/base_site" %}\n'] 
    271271    raw_template.append('{% block bodyclass %}change-list{% endblock %}\n') 
    272272    if not is_popup: 
     
    665665    
    666666    
    667 def add_stage_new(request, app_label, module_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None): 
     667def add_stage(request, app_label, module_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None): 
    668668    mod, opts = _get_mod_opts(app_label, module_name) 
    669669    if not request.user.has_perm(app_label + '.' + opts.get_add_permission()): 
     
    725725    fill_extra_context(opts, app_label, c, add=True) 
    726726    
    727     return render_to_response("admin_change_form", context_instance=c)  
    728 add_stage_new = staff_member_required(add_stage_new
    729  
    730  
    731 def change_stage_new(request, app_label, module_name, object_id): 
     727    return render_to_response("admin/change_form", context_instance=c)  
     728add_stage = staff_member_required(add_stage
     729 
     730 
     731def change_stage(request, app_label, module_name, object_id): 
    732732    mod, opts = _get_mod_opts(app_label, module_name) 
    733733    if not request.user.has_perm(app_label + '.' + opts.get_change_permission()): 
     
    822822    fill_extra_context(opts, app_label, c, change=True) 
    823823     
    824     return render_to_response('admin_change_form', context_instance=c) 
    825 change_stage_new = staff_member_required(change_stage_new) 
    826  
    827 def _get_template(opts, app_label, add=False, change=False, show_delete=False, form_url=''): 
    828     admin_field_objs = opts.admin.get_field_objs(opts) 
    829     ordered_objects = opts.get_ordered_objects()[:] 
    830     auto_populated_fields = [f for f in opts.fields if f.prepopulate_from] 
    831     t = ['{% extends "base_site" %}\n'] 
    832     t.append('{% block extrahead %}') 
    833  
    834     # Put in any necessary JavaScript imports. 
    835     javascript_imports = ['%sjs/core.js' % ADMIN_MEDIA_PREFIX, '%sjs/admin/RelatedObjectLookups.js' % ADMIN_MEDIA_PREFIX] 
    836     if auto_populated_fields: 
    837         javascript_imports.append('%sjs/urlify.js' % ADMIN_MEDIA_PREFIX) 
    838     if opts.has_field_type(meta.DateTimeField) or opts.has_field_type(meta.TimeField) or opts.has_field_type(meta.DateField): 
    839         javascript_imports.extend(['%sjs/calendar.js' % ADMIN_MEDIA_PREFIX, '%sjs/admin/DateTimeShortcuts.js' % ADMIN_MEDIA_PREFIX]) 
    840     if ordered_objects: 
    841         javascript_imports.extend(['%sjs/getElementsBySelector.js' % ADMIN_MEDIA_PREFIX, '%sjs/dom-drag.js' % ADMIN_MEDIA_PREFIX, '%sjs/admin/ordering.js' % ADMIN_MEDIA_PREFIX]) 
    842     if opts.admin.js: 
    843         javascript_imports.extend(opts.admin.js) 
    844     seen_collapse = False 
    845     for _, options in admin_field_objs: 
    846         if not seen_collapse and 'collapse' in options.get('classes', ''): 
    847             seen_collapse = True 
    848             javascript_imports.append('%sjs/admin/CollapsedFieldsets.js' % ADMIN_MEDIA_PREFIX) 
    849         try: 
    850             for field_list in options['fields']: 
    851                 for f in field_list: 
    852                     if f.rel and isinstance(f, meta.ManyToManyField) and f.rel.filter_interface: 
    853                         javascript_imports.extend(['%sjs/SelectBox.js' % ADMIN_MEDIA_PREFIX, '%sjs/SelectFilter2.js' % ADMIN_MEDIA_PREFIX]) 
    854                         raise StopIteration 
    855         except StopIteration: 
    856             break 
    857     for j in javascript_imports: 
    858         t.append('<script type="text/javascript" src="%s"></script>' % j) 
    859  
    860     t.append('{% endblock %}\n') 
    861     if ordered_objects: 
    862         coltype = 'colMS' 
    863     else: 
    864         coltype = 'colM' 
    865     t.append('{%% block coltype %%}%s{%% endblock %%}\n' % coltype) 
    866     t.append('{%% block bodyclass %%}%s-%s change-form{%% endblock %%}\n' % (app_label, opts.object_name.lower())) 
    867     breadcrumb_title = add and "Add %s" % opts.verbose_name or '{{ original|striptags|truncatewords:"18" }}' 
    868     t.append('{%% block breadcrumbs %%}{%% if not is_popup %%}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../">%s</a> &rsaquo; %s</div>{%% endif %%}{%% endblock %%}\n' % \ 
    869         (capfirst(opts.verbose_name_plural), breadcrumb_title)) 
    870     t.append('{% block content %}<div id="content-main">\n') 
    871     if change: 
    872         t.append('{% if not is_popup %}') 
    873         t.append('<ul class="object-tools"><li><a href="history/" class="historylink">History</a></li>') 
    874         if hasattr(opts.get_model_module().Klass, 'get_absolute_url'): 
    875             t.append('<li><a href="/r/%s/{{ object_id }}/" class="viewsitelink">View on site</a></li>' % opts.get_content_type_id()) 
    876         t.append('</ul>\n') 
    877         t.append('{% endif %}') 
    878     t.append('<form ') 
    879     if opts.has_field_type(meta.FileField): 
    880         t.append('enctype="multipart/form-data" ') 
    881     t.append('action="%s" method="post">\n' % form_url) 
    882     t.append('{% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %}') 
    883     if opts.admin.save_on_top: 
    884         t.extend(_get_submit_row_template(opts, app_label, add, change, show_delete, ordered_objects)) 
    885     t.append('{% if form.error_dict %}<p class="errornote">Please correct the error{{ form.error_dict.items|pluralize }} below.</p>{% endif %}\n') 
    886     for fieldset_name, options in admin_field_objs: 
    887         t.append('<fieldset class="module aligned %s">\n\n' % options.get('classes', '')) 
    888         if fieldset_name: 
    889             t.append('<h2>%s</h2>\n' % fieldset_name) 
    890         for field_list in options['fields']: 
    891             t.append(_get_admin_field(field_list, 'form.', False, add, change)) 
    892             for f in field_list: 
    893                 if f.rel and isinstance(f, meta.ManyToManyField) and f.rel.filter_interface: 
    894                     t.append('<script type="text/javascript">addEvent(window, "load", function(e) { SelectFilter.init("id_%s", "%s", %s, %r); });</script>\n' % (f.name, f.verbose_name, f.rel.filter_interface-1, ADMIN_MEDIA_PREFIX)) 
    895         t.append('</fieldset>\n') 
    896     if ordered_objects and change: 
    897         t.append('<fieldset class="module"><h2>Ordering</h2>') 
    898         t.append('<div class="form-row{% if form.order_.errors %} error{% endif %} ">\n') 
    899         t.append('{% if form.order_.errors %}{{ form.order_.html_error_list }}{% endif %}') 
    900         t.append('<p><label for="id_order_">Order:</label> {{ form.order_ }}</p>\n') 
    901         t.append('</div></fieldset>\n') 
    902     for rel_obj, rel_field in opts.get_inline_related_objects(): 
    903         var_name = rel_obj.object_name.lower() 
    904         field_list = [f for f in rel_obj.fields + rel_obj.many_to_many if f.editable and f != rel_field] 
    905  
    906         t.append('<fieldset class="module%s">\n' % ((rel_field.rel.edit_inline != meta.TABULAR) and ' aligned' or '')) 
    907         view_on_site = '' 
    908         if change and hasattr(rel_obj, 'get_absolute_url'): 
    909             view_on_site = '{%% if %s.original %%}<a href="/r/{{ %s.content_type_id }}/{{ %s.original.id }}/">View on site</a>{%% endif %%}' % (var_name, var_name, var_name) 
    910         if rel_field.rel.edit_inline == meta.TABULAR: 
    911             t.append('<h2>%s</h2>\n<table>\n' % capfirst(rel_obj.verbose_name_plural)) 
    912             t.append('<thead><tr>') 
    913             for f in field_list: 
    914                 if isinstance(f, meta.AutoField): 
    915                     continue 
    916                 t.append('<th%s>%s</th>' % (f.blank and ' class="optional"' or '', capfirst(f.verbose_name))) 
    917             t.append('</tr></thead>\n') 
    918             t.append('{%% for %s in form.%s %%}\n' % (var_name, rel_obj.module_name)) 
    919             if change: 
    920                 for f in field_list: 
    921                     if use_raw_id_admin(f): 
    922                         t.append('{%% if %s.original %%}' % var_name) 
    923                         t.append('<tr class="row-label {% cycle row1,row2 %}">') 
    924                         t.append('<td colspan="%s"><strong>{{ %s.original }}</strong></td>' % (30, var_name)) 
    925                         t.append('</tr>{% endif %}\n') 
    926                         break 
    927             t.append('{%% if %s %%}\n' % ' or '.join(['%s.%s.errors' % (var_name, f.name) for f in field_list])) 
    928             t.append('<tr class="errorlist"><td colspan="%s">%s</td></tr>\n{%% endif %%}\n' % \ 
    929                 (len(field_list), ''.join(['{{ %s.%s.html_error_list }}' % (var_name, f.name) for f in field_list]))) 
    930             t.append('<tr class="{% cycle row1,row2 %}">\n') 
    931             hidden_fields = [] 
    932             for f in field_list: 
    933                 form_widget = _get_admin_field_form_widget(f, var_name+'.', True, add, change) 
    934                 # Don't put AutoFields within a <td>, because they're hidden. 
    935                 if not isinstance(f, meta.AutoField): 
    936                     # Fields with raw_id_admin=True get class="nowrap". 
    937                     if use_raw_id_admin(f): 
    938                         t.append('<td class="nowrap {%% if %s.%s.errors %%}error"{%% endif %%}">%s</td>\n' % (var_name, f.name, form_widget)) 
    939                     else: 
    940                         t.append('<td{%% if %s.%s.errors %%} class="error"{%% endif %%}>%s</td>\n' % (var_name, f.name, form_widget)) 
    941                 else: 
    942                     hidden_fields.append(form_widget) 
    943             if hasattr(rel_obj, 'get_absolute_url'): 
    944                 t.append('<td>%s</td>\n' % view_on_site) 
    945             t.append('</tr>\n') 
    946             t.append('{% endfor %}\n</table>\n') 
    947             # Write out the hidden fields. We didn't write them out earlier 
    948             # because it would've been invalid HTML. 
    949             t.append('{%% for %s in form.%s %%}\n' % (var_name, rel_obj.module_name)) 
    950             t.extend(hidden_fields) 
    951             t.append('{% endfor %}\n') 
    952         else: # edit_inline == STACKED 
    953             t.append('{%% for %s in form.%s %%}' % (var_name, rel_obj.module_name)) 
    954             t.append('<h2>%s #{{ forloop.counter }}</h2>' % capfirst(rel_obj.verbose_name)) 
    955             if view_on_site: 
    956                 t.append('<p>%s</p>' % view_on_site) 
    957             for f in field_list: 
    958                 # Don't put AutoFields within the widget -- just use the field. 
    959                 if isinstance(f, meta.AutoField): 
    960                     t.append(_get_admin_field_form_widget(f, var_name+'.', True, add, change)) 
    961                 else: 
    962                     t.append(_get_admin_field([f], var_name+'.', True, add, change)) 
    963             t.append('{% endfor %}\n') 
    964         t.append('</fieldset>\n') 
    965     t.extend(_get_submit_row_template(opts, app_label, add, change, show_delete, ordered_objects)) 
    966     if add: 
    967         # Add focus to the first field on the form, if this is an "add" form. 
    968         t.append('<script type="text/javascript">document.getElementById("id_%s").focus();</script>' % \ 
    969             admin_field_objs[0][1]['fields'][0][0].get_manipulator_field_names('')[0]) 
    970     if auto_populated_fields: 
    971         t.append('<script type="text/javascript">') 
    972         for field in auto_populated_fields: 
    973             if change: 
    974                 t.append('document.getElementById("id_%s")._changed = true;' % field.name) 
    975             else: 
    976                 t.append('document.getElementById("id_%s").onchange = function() { this._changed = true; };' % field.name) 
    977             for f in field.prepopulate_from: 
    978                 t.append('document.getElementById("id_%s").onkeyup = function() { var e = document.getElementById("id_%s"); if (!e._changed) { e.value = URLify(%s, %s);}};' % \ 
    979                     (f, field.name, ' + " " + '.join(['document.getElementById("id_%s").value' % g for g in field.prepopulate_from]), field.maxlength)) 
    980         t.append('</script>\n') 
    981     if change and ordered_objects: 
    982         t.append('{% if form.order_objects %}<ul id="orderthese">{% for object in form.order_objects %}') 
    983         t.append('<li id="p{%% firstof %(x)s %%}"><span id="handlep{%% firstof %(x)s %%}">{{ object|truncatewords:"5" }}</span></li>' % \ 
    984             {'x': ' '.join(['object.%s' % o.pk.name for o in ordered_objects])}) 
    985         t.append('{% endfor %}</ul>{% endif %}\n') 
    986     t.append('</form>\n</div>\n{% endblock %}') 
    987     return ''.join(t) 
    988  
    989 def _get_admin_field(field_list, name_prefix, rel, add, change): 
    990     "Returns the template code for editing the given list of fields in the admin template." 
    991     field_names = [] 
    992     for f in field_list: 
    993         field_names.extend(f.get_manipulator_field_names(name_prefix)) 
    994     div_class_names = ['form-row', '{%% if %s %%} error{%% endif %%}' % ' or '.join(['%s.errors' % n for n in field_names])] 
    995     # Assumes BooleanFields won't be stacked next to each other! 
    996     if isinstance(field_list[0], meta.BooleanField): 
    997         div_class_names.append('checkbox-row') 
    998     t = [] 
    999     t.append('<div class="%s">\n' % ' '.join(div_class_names)) 
    1000     for n in field_names: 
    1001         t.append('{%% if %s.errors %%}{{ %s.html_error_list }}{%% endif %%}\n' % (n, n)) 
    1002     for i, field in enumerate(field_list): 
    1003         label_name = 'id_%s%s' % ((rel and "%s{{ forloop.counter0 }}." % name_prefix or ""), field.get_manipulator_field_names('')[0]) 
    1004         # BooleanFields are a special case, because the checkbox widget appears to 
    1005         # the *left* of the label. 
    1006         if isinstance(field, meta.BooleanField): 
    1007             t.append(_get_admin_field_form_widget(field, name_prefix, rel, add, change)) 
    1008             t.append(' <label for="%s" class="vCheckboxLabel">%s</label>' % (label_name, capfirst(field.verbose_name))) 
    1009         else: 
    1010             class_names = [] 
    1011             if not field.blank: 
    1012                 class_names.append('required') 
    1013             if i > 0: 
    1014                 class_names.append('inline') 
    1015             t.append('<label for="%s"%s>%s:</label> ' % (label_name, class_names and ' class="%s"' % ' '.join(class_names) or '', capfirst(field.verbose_name))) 
    1016             t.append(_get_admin_field_form_widget(field, name_prefix, rel, add, change)) 
    1017         if change and field.primary_key: 
    1018             t.append('{{ %soriginal.%s }}' % ((rel and name_prefix or ''), field.name)) 
    1019         if change and use_raw_id_admin(field): 
    1020             if isinstance(field.rel, meta.ManyToOne): 
    1021                 if_bit = '%soriginal.get_%s' % (rel and name_prefix or '', field.name) 
    1022                 obj_repr = if_bit + '|truncatewords:"14"' 
    1023             elif isinstance(field.rel, meta.ManyToMany): 
    1024                 if_bit = '%soriginal.get_%s_list' % (rel and name_prefix or '', field.name) 
    1025                 obj_repr = if_bit + '|join:", "|truncatewords:"14"' 
    1026             t.append('{%% if %s %%}&nbsp;<strong>{{ %s }}</strong>{%% endif %%}' % (if_bit, obj_repr)) 
    1027         if field.help_text: 
    1028             t.append('<p class="help">%s</p>\n' % field.help_text) 
    1029     t.append('</div>\n\n') 
    1030     return ''.join(t) 
    1031  
    1032 def _get_admin_field_form_widget(field, name_prefix, rel, add, change): 
    1033     "Returns JUST the formfield widget for the field's admin interface." 
    1034     field_names = field.get_manipulator_field_names(name_prefix) 
    1035     if isinstance(field, meta.DateTimeField): 
    1036         return '<p class="datetime">Date: {{ %s }}<br />Time: {{ %s }}</p>' % tuple(field_names) 
    1037     t = ['{{ %s }}' % n for n in field_names] 
    1038     if change and isinstance(field, meta.FileField): 
    1039         return '{%% if %soriginal.%s %%}Currently: <a href="{{ %soriginal.get_%s_url }}">{{ %soriginal.%s }}</a><br />Change: %s{%% else %%}%s{%% endif %%}' % \ 
    1040             (name_prefix, field.name, name_prefix, field.name, name_prefix, field.name, ''.join(t), ''.join(t)) 
    1041     field_id = 'id_%s%s' % ((rel and "%s{{ forloop.counter0 }}." % name_prefix or ""), field.get_manipulator_field_names('')[0]) 
    1042     # raw_id_admin fields get the little lookup link next to them 
    1043     if use_raw_id_admin(field): 
    1044         t.append(' <a href="../../../%s/%s/" class="related-lookup" id="lookup_%s" onclick="return showRelatedObjectLookupPopup(this);">' % \ 
    1045                     (field.rel.to.app_label, field.rel.to.module_name, field_id)) 
    1046         t.append('<img src="%simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % ADMIN_MEDIA_PREFIX) 
    1047     # fields with relationships to editable objects get an "add another" link, 
    1048     # but only if the field doesn't have raw_admin ('cause in that case they get 
    1049     # the "add" button in the popup) 
    1050     elif field.rel and (isinstance(field.rel, meta.ManyToOne) or isinstance(field.rel, meta.ManyToMany)) and field.rel.to.admin: 
    1051         t.append('{%% if perms.%s.%s %%}' % (field.rel.to.app_label, field.rel.to.get_add_permission())) 
    1052         t.append(' <a href="../../../%s/%s/add/" class="add-another" id="add_%s" onclick="return showAddAnotherPopup(this);">' % \ 
    1053                     (field.rel.to.app_label, field.rel.to.module_name, field_id)) 
    1054         t.append('<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="Add Another" /></a>' % ADMIN_MEDIA_PREFIX) 
    1055         t.append('{% endif %}') 
    1056     return ''.join(t) 
    1057  
    1058 def add_stage(request, app_label, module_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None): 
    1059     mod, opts = _get_mod_opts(app_label, module_name) 
    1060     if not request.user.has_perm(app_label + '.' + opts.get_add_permission()): 
    1061         raise PermissionDenied 
    1062     manipulator = mod.AddManipulator() 
    1063     if request.POST: 
    1064         new_data = request.POST.copy() 
    1065         if opts.has_field_type(meta.FileField): 
    1066             new_data.update(request.FILES) 
    1067         errors = manipulator.get_validation_errors(new_data) 
    1068         if not errors and not request.POST.has_key("_preview"): 
    1069             for f in opts.many_to_many: 
    1070                 if f.rel.raw_id_admin: 
    1071                     new_data.setlist(f.name, new_data[f.name].split(",")) 
    1072             manipulator.do_html2python(new_data) 
    1073             new_object = manipulator.save(new_data) 
    1074             pk_value = getattr(new_object, opts.pk.column) 
    1075             log.log_action(request.user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.ADDITION) 
    1076             msg = 'The %s "%s" was added successfully.' % (opts.verbose_name, new_object) 
    1077             # Here, we distinguish between different save types by checking for 
    1078             # the presence of keys in request.POST. 
    1079             if request.POST.has_key("_continue"): 
    1080                 request.user.add_message("%s You may edit it again below." % msg) 
    1081                 if request.POST.has_key("_popup"): 
    1082                     post_url_continue += "?_popup=1" 
    1083                 return HttpResponseRedirect(post_url_continue % pk_value) 
    1084             if request.POST.has_key("_popup"): 
    1085                 return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \ 
    1086                     (pk_value, repr(new_object).replace('"', '\\"'))) 
    1087             elif request.POST.has_key("_addanother"): 
    1088                 request.user.add_message("%s You may add another %s below." % (msg, opts.verbose_name)) 
    1089                 return HttpResponseRedirect(request.path) 
    1090             else: 
    1091                 request.user.add_message(msg) 
    1092                 return HttpResponseRedirect(post_url) 
    1093         if request.POST.has_key("_preview"): 
    1094             manipulator.do_html2python(new_data) 
    1095     else: 
    1096         new_data = {} 
    1097         # Add default data. 
    1098         for f in opts.fields: 
    1099             if f.has_default(): 
    1100                 new_data.update( f.flatten_data() ) 
    1101             # In required many-to-one fields with only one available choice, 
    1102             # select that one available choice. Note: We have to check that 
    1103             # the length of choices is *2*, not 1, because SelectFields always 
    1104             # have an initial "blank" value. 
    1105             elif not f.blank and ((isinstance(f.rel, meta.ManyToOne) and not f.rel.raw_id_admin) or f.choices) and len(manipulator[f.name].choices) == 2: 
    1106                 new_data[f.name] = manipulator[f.name].choices[1][0] 
    1107         # In required many-to-many fields with only one available choice, 
    1108         # select that one available choice. 
    1109         for f in opts.many_to_many: 
    1110             if not f.blank and not f.rel.edit_inline and not f.rel.raw_id_admin and len(manipulator[f.name].choices) == 1: 
    1111                 new_data[f.name] = [manipulator[f.name].choices[0][0]] 
    1112         # Add default data for related objects. 
    1113         for rel_opts, rel_field in opts.get_inline_related_objects(): 
    1114             var_name = rel_opts.object_name.lower() 
    1115             for i in range(rel_field.rel.num_in_admin): 
    1116                 for f in rel_opts.fields + rel_opts.many_to_many: 
    1117                     if f.has_default(): 
    1118                         for field_name in f.get_manipulator_field_names(''): 
    1119                             new_data['%s.%d.%s' % (var_name, i, field_name)] = f.get_default() 
    1120         # Override the defaults with request.GET, if it exists. 
    1121         new_data.update(request.GET) 
    1122         errors = {} 
    1123  
    1124     # Populate the FormWrapper. 
    1125     form = formfields.FormWrapper(manipulator, new_data, errors) 
    1126     for rel_opts, rel_field in opts.get_inline_related_objects(): 
    1127         var_name = rel_opts.object_name.lower() 
    1128         wrapper = [] 
    1129         for i in range(rel_field.rel.num_in_admin): 
    1130             collection = {} 
    1131             for f in rel_opts.fields + rel_opts.many_to_many: 
    1132                 if f.editable and f != rel_field and not isinstance(f, meta.AutoField): 
    1133                     for field_name in f.get_manipulator_field_names(''): 
    1134                         full_field_name = '%s.%d.%s' % (var_name, i, field_name) 
    1135                         field = manipulator[full_field_name] 
    1136                         data = field.extract_data(new_data) 
    1137                         collection[field_name] = formfields.FormFieldWrapper(field, data, errors.get(full_field_name, [])) 
    1138             wrapper.append(formfields.FormFieldCollection(collection)) 
    1139         setattr(form, rel_opts.module_name, wrapper) 
    1140  
    1141     c = Context(request, { 
    1142         'title': 'Add %s' % opts.verbose_name, 
    1143         "form": form, 
    1144         "is_popup": request.REQUEST.has_key("_popup"), 
    1145     }) 
    1146     if object_id_override is not None: 
    1147         c['object_id'] = object_id_override 
    1148     raw_template = _get_template(opts, app_label, add=True, show_delete=show_delete, form_url=form_url) 
    1149     t = loader.get_template_from_string(raw_template) 
    1150     return HttpResponse(t.render(c)) 
    1151 add_stage = staff_member_required(add_stage) 
    1152  
    1153 def change_stage(request, app_label, module_name, object_id): 
    1154     mod, opts = _get_mod_opts(app_label, module_name) 
    1155     if not request.user.has_perm(app_label + '.' + opts.get_change_permission()): 
    1156         raise PermissionDenied 
    1157     if request.POST and request.POST.has_key("_saveasnew"): 
    1158         return add_stage(request, app_label, module_name, form_url='../add/') 
    1159     try: 
    1160         manipulator = mod.ChangeManipulator(object_id) 
    1161     except ObjectDoesNotExist: 
    1162         raise Http404 
    1163  
    1164     inline_related_objects = opts.get_inline_related_objects() 
    1165     if request.POST: 
    1166         new_data = request.POST.copy() 
    1167         if opts.has_field_type(meta.FileField): 
    1168             new_data.update(request.FILES) 
    1169  
    1170         errors = manipulator.get_validation_errors(new_data) 
    1171         if not errors and not request.POST.has_key("_preview"): 
    1172             for f in opts.many_to_many: 
    1173                 if f.rel.raw_id_admin: 
    1174                     new_data.setlist(f.name, new_data[f.name].split(",")) 
    1175             manipulator.do_html2python(new_data) 
    1176             new_object = manipulator.save(new_data) 
    1177             pk_value = getattr(new_object, opts.pk.column) 
    1178  
    1179             # Construct the change message. 
    1180             change_message = [] 
    1181             if manipulator.fields_added: 
    1182                 change_message.append('Added %s.' % get_text_list(manipulator.fields_added, 'and')) 
    1183             if manipulator.fields_changed: 
    1184                 change_message.append('Changed %s.' % get_text_list(manipulator.fields_changed, 'and')) 
    1185             if manipulator.fields_deleted: 
    1186                 change_message.append('Deleted %s.' % get_text_list(manipulator.fields_deleted, 'and')) 
    1187             change_message = ' '.join(change_message) 
    1188             if not change_message: 
    1189                 change_message = 'No fields changed.' 
    1190  
    1191             log.log_action(request.user.id, opts.get_content_type_id(), pk_value, repr(new_object), log.CHANGE, change_message) 
    1192             msg = 'The %s "%s" was changed successfully.' % (opts.verbose_name, new_object) 
    1193             if request.POST.has_key("_continue"): 
    1194                 request.user.add_message("%s You may edit it again below." % msg) 
    1195                 if request.REQUEST.has_key('_popup'): 
    1196                     return HttpResponseRedirect(request.path + "?_popup=1") 
    1197                 else: 
    1198                     return HttpResponseRedirect(request.path) 
    1199             elif request.POST.has_key("_saveasnew"): 
    1200                 request.user.add_message('The %s "%s" was added successfully. You may edit it again below.' % (opts.verbose_name, new_object)) 
    1201                 return HttpResponseRedirect("../%s/" % pk_value) 
    1202             elif request.POST.has_key("_addanother"): 
    1203                 request.user.add_message("%s You may add another %s below." % (msg, opts.verbose_name)) 
    1204                 return HttpResponseRedirect("../add/") 
    1205             else: 
    1206                 request.user.add_message(msg) 
    1207                 return HttpResponseRedirect("../") 
    1208         if request.POST.has_key("_preview"): 
    1209             manipulator.do_html2python(new_data) 
    1210     else: 
    1211         # Populate new_data with a "flattened" version of the current data. 
    1212         new_data = {} 
    1213         obj = manipulator.original_object 
    1214         for f in opts.fields: 
    1215             new_data.update(f.flatten_data(obj)) 
    1216         for f in opts.many_to_many: 
    1217             get_list_func = getattr(obj, 'get_%s_list' % f.rel.singular) 
    1218             if f.rel.raw_id_admin: 
    1219                 new_data[f.name] = ",".join([str(getattr(i, f.rel.to.pk.column)) for i in get_list_func()]) 
    1220             elif not f.rel.edit_inline: 
    1221                 new_data[f.name] = [getattr(i, f.rel.to.pk.column) for i in get_list_func()] 
    1222         for rel_obj, rel_field in inline_related_objects: 
    1223             var_name = rel_obj.object_name.lower() 
    1224             for i, rel_instance in enumerate(getattr(obj, 'get_%s_list' % opts.get_rel_object_method_name(rel_obj, rel_field))()): 
    1225                 for f in rel_obj.fields: 
    1226                     if f.editable and f != rel_field: 
    1227                         for k, v in f.flatten_data(rel_instance).items(): 
    1228                             new_data['%s.%d.%s' % (var_name, i, k)] = v 
    1229                 for f in rel_obj.many_to_many: 
    1230                     new_data['%s.%d.%s' % (var_name, i, f.column)] = [j.id for j in getattr(rel_instance, 'get_%s_list' % f.rel.singular)()] 
    1231  
    1232         # If the object has ordered objects on its admin page, get the existing 
    1233         # order and flatten it into a comma-separated list of IDs. 
    1234         id_order_list = [] 
    1235         for rel_obj in opts.get_ordered_objects(): 
    1236             id_order_list.extend(getattr(obj, 'get_%s_order' % rel_obj.object_name.lower())()) 
    1237         if id_order_list: 
    1238             new_data['order_'] = ','.join(map(str, id_order_list)) 
    1239         errors = {} 
    1240  
    1241     # Populate the FormWrapper. 
    1242     form = formfields.FormWrapper(manipulator, new_data, errors) 
    1243     form.original = manipulator.original_object 
    1244     form.order_objects = [] 
    1245     for rel_opts, rel_field in inline_related_objects: 
    1246         var_name = rel_opts.object_name.lower() 
    1247         wrapper = [] 
    1248         orig_list = getattr(manipulator.original_object, 'get_%s_list' % opts.get_rel_object_method_name(rel_opts, rel_field))() 
    1249         count = len(orig_list) + rel_field.rel.num_extra_on_change 
    1250         if rel_field.rel.min_num_in_admin: 
    1251             count = max(count, rel_field.rel.min_num_in_admin) 
    1252         if rel_field.rel.max_num_in_admin: 
    1253             count = min(count, rel_field.rel.max_num_in_admin) 
    1254         for i in range(count): 
    1255             collection = {'original': (i < len(orig_list) and orig_list[i] or None)} 
    1256             for f in rel_opts.fields + rel_opts.many_to_many: 
    1257                 if f.editable and f != rel_field: 
    1258                     for field_name in f.get_manipulator_field_names(''): 
    1259