Ticket #16260: 16260-admin-popup-callback.diff
File 16260-admin-popup-callback.diff, 12.0 KB (added by , 12 years ago) |
---|
-
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 4d23f8f..5e78bce 100644
a b class ModelAdmin(BaseModelAdmin): 776 776 self.message_user(request, msg + ' ' + _("You may edit it again below.")) 777 777 if "_popup" in request.POST: 778 778 post_url_continue += "?_popup=1" 779 if '_callback' in request.REQUEST: 780 post_url_continue += '&_callback=%s' % request.REQUEST.get('_callback') 779 781 return HttpResponseRedirect(post_url_continue % pk_value) 780 782 781 783 if "_popup" in request.POST: 784 popup_callback = request.REQUEST.get('_callback', 'dismissAddAnotherPopup') 782 785 return HttpResponse( 783 786 '<!DOCTYPE html><html><head><title></title></head><body>' 784 '<script type="text/javascript">opener. dismissAddAnotherPopup(window, "%s", "%s");</script></body></html>' % \787 '<script type="text/javascript">opener.%s(window, "%s", "%s");</script></body></html>' % \ 785 788 # escape() calls force_unicode. 786 ( escape(pk_value), escapejs(obj)))789 (popup_callback, escape(pk_value), escapejs(obj))) 787 790 elif "_addanother" in request.POST: 788 791 self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 789 792 return HttpResponseRedirect(request.path) … … class ModelAdmin(BaseModelAdmin): 1004 1007 'errors': helpers.AdminErrorList(form, formsets), 1005 1008 'app_label': opts.app_label, 1006 1009 } 1010 if '_callback' in request.REQUEST: 1011 context.update({'popup_callback': request.REQUEST.get('_callback')}) 1007 1012 context.update(extra_context or {}) 1008 1013 return self.render_change_form(request, context, form_url=form_url, add=True) 1009 1014 … … class ModelAdmin(BaseModelAdmin): 1234 1239 'selection_note_all': selection_note_all % {'total_count': cl.result_count}, 1235 1240 'title': cl.title, 1236 1241 'is_popup': cl.is_popup, 1242 'popup_callback': cl.popup_callback, 1237 1243 'cl': cl, 1238 1244 'media': media, 1239 1245 'has_add_permission': self.has_add_permission(request), -
django/contrib/admin/templates/admin/change_form.html
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html index 82d7296..937f0c1 100644
a b 37 37 {% endblock %} 38 38 <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}{% block form_top %}{% endblock %} 39 39 <div> 40 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}40 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% if popup_callback %}<input type="hidden" name="_callback" value="{{ popup_callback }}" />{% endif %}{% endif %} 41 41 {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %} 42 42 {% if errors %} 43 43 <p class="errornote"> -
django/contrib/admin/templates/admin/change_list.html
diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html index c72b663..c6b82ca 100644
a b 54 54 <ul class="object-tools"> 55 55 {% block object-tools-items %} 56 56 <li> 57 <a href="{% url cl.opts|admin_urlname:'add' %}{% if is_popup %}?_popup=1{% endif %}" class="addlink">57 <a href="{% url cl.opts|admin_urlname:'add' %}{% if is_popup %}?_popup=1{% if popup_callback %}&_callback={{ popup_callback }}{% endif %}{% endif %}" class="addlink"> 58 58 {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %} 59 59 </a> 60 60 </li> -
django/contrib/admin/templatetags/admin_list.py
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 0f15781..92e4878 100644
a b def items_for_result(cl, result, form): 228 228 table_tag, 229 229 row_class, 230 230 url, 231 format_html(' onclick="opener.dismissRelatedLookupPopup(window, {0}); return false;"', result_id) 232 if cl.is_popup else '', 231 format_html( 232 ' onclick="opener.{0}(window, {1}); return false;"', 233 cl.get_popup_callback(), result_id 234 ) if cl.is_popup else '', 233 235 result_repr, 234 236 table_tag) 235 237 else: -
django/contrib/admin/views/main.py
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 85e03f3..ffd351b 100644
a b SEARCH_VAR = 'q' 24 24 TO_FIELD_VAR = 't' 25 25 IS_POPUP_VAR = 'pop' 26 26 ERROR_FLAG = 'e' 27 POPUP_CALLBACK_VAR = '_callback' 28 POPUP_CALLBACK_DEFAULT = 'dismissRelatedLookupPopup' 27 29 28 30 IGNORED_PARAMS = ( 29 ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR) 31 ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR, 32 POPUP_CALLBACK_VAR) 30 33 31 34 # Text to display within change-list table cells if the value is blank. 32 35 EMPTY_CHANGELIST_VALUE = ugettext_lazy('(None)') … … class ChangeList(object): 57 60 self.page_num = 0 58 61 self.show_all = ALL_VAR in request.GET 59 62 self.is_popup = IS_POPUP_VAR in request.GET 63 self.popup_callback = request.REQUEST.get(POPUP_CALLBACK_VAR) 60 64 self.to_field = request.GET.get(TO_FIELD_VAR) 61 65 self.params = dict(request.GET.items()) 62 66 if PAGE_VAR in self.params: … … class ChangeList(object): 377 381 378 382 def url_for_result(self, result): 379 383 return "%s/" % quote(getattr(result, self.pk_attname)) 384 385 def get_popup_callback(self): 386 if self.popup_callback is not None: 387 return self.popup_callback 388 return POPUP_CALLBACK_DEFAULT 389 No newline at end of file -
new file tests/regressiontests/admin_related_lookup_popup/models.py
diff --git a/tests/regressiontests/admin_related_lookup_popup/__init__.py b/tests/regressiontests/admin_related_lookup_popup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/regressiontests/admin_related_lookup_popup/models.py b/tests/regressiontests/admin_related_lookup_popup/models.py new file mode 100644 index 0000000..aa1e83e
- + 1 from django.db import models 2 from django.contrib import admin 3 4 5 __all__ = ['RelatedItem', 'AnotherRelatedItem'] 6 7 8 class RelatedItem(models.Model): 9 title = models.CharField(max_length=25, blank=True, null=True) 10 11 def __unicode__(self): 12 return self.title 13 14 class AnotherRelatedItem(models.Model): 15 title = models.CharField(max_length=15, blank=True, null=True) 16 17 def __unicode__(self): 18 return self.title 19 20 21 admin.site.register(RelatedItem, None) 22 admin.site.register(AnotherRelatedItem, None) -
new file tests/regressiontests/admin_related_lookup_popup/tests.py
diff --git a/tests/regressiontests/admin_related_lookup_popup/tests.py b/tests/regressiontests/admin_related_lookup_popup/tests.py new file mode 100644 index 0000000..1cffd8e
- + 1 """ 2 This file demonstrates writing tests using the unittest module. These will pass 3 when you run "manage.py test". 4 5 Replace this with more appropriate tests for your application. 6 """ 7 8 from django.contrib.admin.views.main import IS_POPUP_VAR, POPUP_CALLBACK_VAR 9 from django.contrib.auth.models import User 10 from django.core.urlresolvers import reverse 11 from django.test import TestCase 12 from models import * 13 14 15 class login(object): 16 def __init__(self, testcase, user, password): 17 self.testcase = testcase 18 success = testcase.client.login(username=user, password=password) 19 self.testcase.assertTrue( 20 success, 21 "login with username=%r, password=%r failed" % (user, password) 22 ) 23 24 def __enter__(self): 25 pass 26 27 def __exit__(self, *args): 28 self.testcase.client.logout() 29 30 31 class RelatedLookupPopupTest(TestCase): 32 33 def setUp(self): 34 User.objects.create_superuser('root', 'root@example.com', '123') 35 RelatedItem.objects.create(title='lorem') 36 RelatedItem.objects.create(title='ipsum') 37 RelatedItem.objects.create(title='dolorem') 38 39 AnotherRelatedItem.objects.create(title='lorem') 40 AnotherRelatedItem.objects.create(title='ipsum') 41 AnotherRelatedItem.objects.create(title='dolorem') 42 AnotherRelatedItem.objects.create(title='lorem') 43 AnotherRelatedItem.objects.create(title='ipsum') 44 45 def test_choose_from_changelist(self): 46 with login(self, 'root', '123'): 47 callbacks = { 48 'dismissRelatedItemLookupPopup': (reverse('admin:admin_related_lookup_popup_relateditem_changelist'), 3), 49 'dismissAnoterRelatedItemLookupPopup': (reverse('admin:admin_related_lookup_popup_anotherrelateditem_changelist'), 5), 50 } 51 52 for callback_name, opts in callbacks.items(): 53 changelist_url, count = opts 54 55 response = self.client.get("%s?_callback=%s" % (changelist_url, callback_name)) 56 self.assertContains(response, '<a href="1/">', 1, 200) 57 self.assertContains(response, '<a href="2/">', 1, 200) 58 self.assertContains(response, '<a href="3/">', 1, 200) 59 self.assertContains(response, 'onclick="opener.%s(' % callback_name, 0, 200) 60 61 response = self.client.get("%s?%s=1&_callback=%s" % \ 62 (changelist_url, IS_POPUP_VAR, callback_name)) 63 self.assertContains(response, '<a href="1/">', 0, 200) 64 self.assertContains(response, '<a href="2/">', 0, 200) 65 self.assertContains(response, '<a href="3/">', 0, 200) 66 self.assertContains(response, 'onclick="opener.%s(' % callback_name, count, 200) 67 68 def test_add_new_related(self): 69 with login(self, 'root', '123'): 70 callback_name = 'dismissRelatedItemLookupPopup' 71 add_url = reverse('admin:admin_related_lookup_popup_relateditem_add') 72 73 # check correct rendering form 74 response = self.client.get("%s?_popup=1&_callback=%s" % (add_url, callback_name)) 75 self.assertEqual(response.status_code, 200) 76 self.assertContains(response, '<input type="hidden" name="_popup" value="1" />', 1, 200) 77 self.assertContains(response, '<input type="hidden" name="_callback" value="%s" />' % callback_name, 1, 200) 78 79 # check correct posting form 80 response = self.client.post(add_url, { 81 'title': 'zxc', 82 '_popup': 1, 83 '_callback': callback_name, 84 }) 85 self.assertEqual(response.status_code, 200) 86 self.assertContains(response, '<script') 87 self.assertContains(response, callback_name) 88 89 def test_choose_new_from_changelist(self): 90 with login(self, 'root', '123'): 91 callback_name = 'dismissRelatedItemLookupPopup' 92 changelist_url = reverse('admin:admin_related_lookup_popup_relateditem_changelist') 93 94 response = self.client.get("%s?%s=1" % (changelist_url, IS_POPUP_VAR)) 95 self.assertContains(response, 'add/?_popup=1', 1, 200) 96 97 response = self.client.get("%s?%s=1&%s=%s" % \ 98 (changelist_url, IS_POPUP_VAR, POPUP_CALLBACK_VAR, callback_name)) 99 self.assertContains(response, 'add/?_popup=1&_callback=%s' % callback_name, 1, 200)