Ticket #7028: patch7028-1.4.rev16669.patch
File patch7028-1.4.rev16669.patch, 13.6 KB (added by , 13 years ago) |
---|
-
django/contrib/admin/options.py
5 5 inlineformset_factory, BaseInlineFormSet) 6 6 from django.contrib.contenttypes.models import ContentType 7 7 from django.contrib.admin import widgets, helpers 8 from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_format_dict 8 from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_format_dict, obj_label 9 9 from django.contrib.admin.templatetags.admin_static import static 10 10 from django.contrib import messages 11 11 from django.views.decorators.csrf import csrf_protect 12 12 from django.core.exceptions import PermissionDenied, ValidationError 13 13 from django.core.paginator import Paginator 14 from django.core.urlresolvers import reverse 14 15 from django.db import models, transaction, router 15 16 from django.db.models.related import RelatedObject 16 17 from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist … … 801 802 return HttpResponseRedirect(request.path + "?_popup=1") 802 803 else: 803 804 return HttpResponseRedirect(request.path) 805 elif "_popup" in request.POST: 806 # object changed via raw id link popup 807 obj_id = repr(force_unicode(obj._get_pk_val()))[1:] 808 obj_url = reverse('admin:%s_%s_change' % (opts.app_label, opts.object_name.lower()), args=(obj.pk,), current_app=self.admin_site.name) 809 label = obj_label(obj).replace("'", r"\'") 810 return HttpResponse('<script type="text/javascript">opener.dismissRelatedLookupPopup(' 811 "window, %s, '%s', '%s');</script>" % (obj_id, obj_url, label)) 804 812 elif "_saveasnew" in request.POST: 805 813 msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj} 806 814 self.message_user(request, msg) -
django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
11 11 return text; 12 12 } 13 13 14 function html_escape(text) { 15 text = text.replace(/&/g, '&'); 16 text = text.replace(/</g, '<'); 17 text = text.replace(/>/g, '>'); 18 text = text.replace(/"/g, '"'); 19 text = text.replace(/'/g, '''); 20 return text; 21 } 22 14 23 // IE doesn't accept periods or dashes in the window name, but the element IDs 15 24 // we use to generate popup window names may contain them, therefore we map them 16 25 // to allowed characters in a reversible way so that we can locate the correct … … 27 36 return text; 28 37 } 29 38 39 function getAdminMediaPrefix() { 40 // Copy-paste from DateTimeShortcuts.js. 41 if (window.__admin_media_prefix__ != undefined) { 42 return window.__admin_media_prefix__; 43 } else { 44 return '/missing-admin-media-prefix/'; 45 } 46 } 47 48 var CLEAR_RAW_ID = '<a href="#" onclick="return clearRawId(this);">' + 49 '<img src="' + getAdminMediaPrefix() + 'img/icon_deletelink.gif" ' + 50 'width="10" height="10" alt="Clear" title="Clear" /></a>'; 51 52 // FIXME: the following produce 'gettext is not defined' errors in FireBug. 53 // Needs to be tracked down. 54 // (jsi18n is generally included before this in admin templates) 55 // 56 // 'width="10" height="10" alt="' + gettext('Clear') + '" title="' + 57 // gettext('Clear') + '" /></a>'; 58 59 function showRelatedObjectPopup(triggeringLink) { 60 var name = triggeringLink.parentNode.id.replace(/^view_lookup_/, ''); 61 name = id_to_windowname(name); 62 return openPopupWindow(triggeringLink.href, '_popup', name); 63 } 64 30 65 function showRelatedObjectLookupPopup(triggeringLink) { 31 66 var name = triggeringLink.id.replace(/^lookup_/, ''); 32 67 name = id_to_windowname(name); 33 var href; 34 if (triggeringLink.href.search(/\?/) >= 0) { 35 href = triggeringLink.href + '&pop=1'; 36 } else { 37 href = triggeringLink.href + '?pop=1'; 38 } 39 var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 40 win.focus(); 41 return false; 68 return openPopupWindow(triggeringLink.href, 'pop', name); 42 69 } 43 70 44 function dismissRelatedLookupPopup(win, chosenId ) {71 function dismissRelatedLookupPopup(win, chosenId, chosenIdHref, chosenName) { 45 72 var name = windowname_to_id(win.name); 46 73 var elem = document.getElementById(name); 74 var nameElem = document.getElementById("view_lookup_" + name); 47 75 if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 48 76 elem.value += ',' + chosenId; 49 77 } else { 50 78 document.getElementById(name).value = chosenId; 51 79 } 80 if (nameElem) { 81 nameElem.innerHTML = '<a href="' + chosenIdHref + '" ' + 82 'onclick="return showRelatedObjectPopup(this);">' + 83 html_escape(chosenName) + '</a> ' + CLEAR_RAW_ID; 84 } 52 85 win.close(); 53 86 } 54 87 55 88 function showAddAnotherPopup(triggeringLink) { 56 89 var name = triggeringLink.id.replace(/^add_/, ''); 57 90 name = id_to_windowname(name); 58 href = triggeringLink.href 59 if (href.indexOf('?') == -1) { 60 href += '?_popup=1'; 61 } else { 62 href += '&_popup=1'; 63 } 64 var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 65 win.focus(); 66 return false; 91 return openPopupWindow(triggeringLink.href, '_popup', name); 67 92 } 68 93 69 94 function dismissAddAnotherPopup(win, newId, newRepr) { 70 95 // newId and newRepr are expected to have previously been escaped by 71 96 // django.utils.html.escape. 72 97 newId = html_unescape(newId); 98 var newRepr_escaped = newRepr; 73 99 newRepr = html_unescape(newRepr); 74 100 var name = windowname_to_id(win.name); 75 101 var elem = document.getElementById(name); … … 84 110 } else { 85 111 elem.value = newId; 86 112 } 113 var nameElem = document.getElementById("view_lookup_" + name); 114 if (nameElem) { 115 var chosenIdHref = win.location.href.replace(/\/add\/[^\/]*$/, 116 '/' + newId + '/'); 117 nameElem.innerHTML = '<a href="' + chosenIdHref + '" ' + 118 'onclick="return showRelatedObjectPopup(this);">' + 119 newRepr_escaped + '</a> ' + CLEAR_RAW_ID; 120 } 87 121 } 88 122 } else { 89 123 var toId = name + "_to"; … … 94 128 } 95 129 win.close(); 96 130 } 131 132 function clearRawId(triggeringLink) { 133 triggeringLink.parentNode.previousSibling.previousSibling.previousSibling.previousSibling.value = ''; 134 triggeringLink.parentNode.innerHTML = ''; 135 return false; 136 } 137 138 function openPopupWindow(href, popup_var, name) { 139 if (href.indexOf('?') == -1) { 140 href += '?'; 141 } else { 142 href += '&'; 143 } 144 href += popup_var + '=1'; 145 var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 146 win.focus(); 147 return false; 148 } -
django/contrib/admin/templatetags/admin_list.py
3 3 from django.contrib.admin.util import lookup_field, display_for_field, label_for_field 4 4 from django.contrib.admin.views.main import (ALL_VAR, EMPTY_CHANGELIST_VALUE, 5 5 ORDER_VAR, PAGE_VAR, SEARCH_VAR) 6 from django.contrib.admin.util import obj_label 6 7 from django.contrib.admin.templatetags.admin_static import static 7 8 from django.core.exceptions import ObjectDoesNotExist 9 from django.core.urlresolvers import reverse 8 10 from django.db import models 9 11 from django.utils import formats 10 12 from django.utils.html import escape, conditional_escape … … 214 216 attr = pk 215 217 value = result.serializable_value(attr) 216 218 result_id = repr(force_unicode(value))[1:] 217 yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \ 218 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag)) 219 result_name = obj_label(result) 220 result_url = reverse('admin:%s_%s_change' % (result._meta.app_label, result._meta.object_name.lower()), 221 args=(result.pk,), 222 current_app=cl.model_admin.admin_site.name) 223 yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % 224 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(' "window, %s, '%s', '%s'); return false;\"" % (result_id, result_url, result_name.replace("'", r"\'")) or ''), conditional_escape(result_repr), table_tag)) 219 225 else: 220 226 # By default the fields come from ModelAdmin.list_editable, but if we pull 221 227 # the fields out of the form instead of list_editable custom admins -
django/contrib/admin/widgets.py
13 13 from django.utils.translation import ugettext as _ 14 14 from django.utils.safestring import mark_safe 15 15 from django.utils.encoding import force_unicode 16 from django.contrib.admin.util import obj_label 16 17 17 18 18 19 class FilteredSelectMultiple(forms.SelectMultiple): … … 149 150 attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook. 150 151 # TODO: "lookup_id_" is hard-coded here. This should instead use 151 152 # the correct API to determine the ID dynamically. 152 extra.append(u' <a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> '153 extra.append(u' <a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> ' 153 154 % (related_url, url, name)) 154 155 extra.append(u'<img src="%s" width="16" height="16" alt="%s" /></a>' 155 156 % (static('admin/img/selector-search.gif'), _('Lookup'))) 156 157 output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra 157 if value: 158 output.append(self.label_for_value(value)) 158 output.append(self.label_for_value(value, 'view_lookup_id_%s' % name)) 159 159 return mark_safe(u''.join(output)) 160 160 161 161 def base_url_parameters(self): … … 167 167 params.update({TO_FIELD_VAR: self.rel.get_related_field().name}) 168 168 return params 169 169 170 def label_for_value(self, value): 171 key = self.rel.get_related_field().name 172 try: 173 obj = self.rel.to._default_manager.using(self.db).get(**{key: value}) 174 return ' <strong>%s</strong>' % escape(Truncator(obj).words(14, truncate='...')) 175 except (ValueError, self.rel.to.DoesNotExist): 176 return '' 170 def label_for_value(self, value, name): 171 if value: 172 key = self.rel.get_related_field().name 173 obj = self.rel.to._default_manager.using( 174 self.db).get(**{key: value}) 175 related_url = reverse('admin:%s_%s_change' % 176 (obj._meta.app_label, 177 obj._meta.module_name), 178 object_id=obj.pk, 179 current_app=self.admin_site.name) 177 180 181 return (' <strong id="%(name)s"><a href="%(url)s" ' 182 'onclick="return showRelatedObjectPopup(this);">%(label)s</a> ' 183 '<a href="#" onclick="return clearRawId(this);">' 184 '<img src="%(img_src)s" ' 185 'width="10" height="10" alt="%(clear)s" title="%(clear)s" />' 186 '</a></strong>' % {'name': name, 'url': related_url, 187 'label': obj_label(obj), 188 'img_src': static('admin/img/icon_deletelink.gif'), 189 'clear': _("Clear"),} 190 ) 191 else: 192 # a placeholder that will be filled in 193 # JavaScript dismissRelatedLookupPopup() 194 return ' <strong id="%s"></strong>' % name 195 196 178 197 class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): 179 198 """ 180 199 A Widget for displaying ManyToMany ids in the "raw_id" interface rather than … … 195 214 def url_parameters(self): 196 215 return self.base_url_parameters() 197 216 198 def label_for_value(self, value ):217 def label_for_value(self, value, name): 199 218 return '' 200 219 201 220 def value_from_datadict(self, data, files, name): -
django/contrib/admin/util.py
6 6 from django.utils import formats 7 7 from django.utils.html import escape 8 8 from django.utils.safestring import mark_safe 9 from django.utils.text import capfirst 9 from django.utils.text import capfirst, truncate_words 10 10 from django.utils.encoding import force_unicode, smart_unicode, smart_str 11 11 from django.utils.translation import ungettext 12 12 from django.core.urlresolvers import reverse … … 302 302 else: 303 303 return smart_unicode(value) 304 304 305 def obj_label(obj): 306 return escape(truncate_words(obj, 7)) 305 307 308 306 309 class NotRelationField(Exception): 307 310 pass 308 311