Ticket #16260: related_lookup_popup.diff
File related_lookup_popup.diff, 11.7 KB (added by , 13 years ago) |
---|
-
tests/regressiontests/admin_related_lookup_popup/tests.py
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 46 def test_choose_from_changelist(self): 47 with login(self, 'root', '123'): 48 callbacks = { 49 'dismissRelatedItemLookupPopup': (reverse('admin:admin_related_lookup_popup_relateditem_changelist'), 3), 50 'dismissAnoterRelatedItemLookupPopup': (reverse('admin:admin_related_lookup_popup_anotherrelateditem_changelist'), 5), 51 } 52 53 for callback_name, opts in callbacks.items(): 54 changelist_url, count = opts 55 56 response = self.client.get("%s?_callback=%s" % (changelist_url, callback_name)) 57 self.assertContains(response, '<a href="1/">', 1, 200) 58 self.assertContains(response, '<a href="2/">', 1, 200) 59 self.assertContains(response, '<a href="3/">', 1, 200) 60 self.assertContains(response, 'onclick="opener.%s(' % callback_name, 0, 200) 61 62 response = self.client.get("%s?%s=1&_callback=%s" % \ 63 (changelist_url, IS_POPUP_VAR, callback_name)) 64 self.assertContains(response, '<a href="1/">', 0, 200) 65 self.assertContains(response, '<a href="2/">', 0, 200) 66 self.assertContains(response, '<a href="3/">', 0, 200) 67 self.assertContains(response, 'onclick="opener.%s(' % callback_name, count, 200) 68 69 70 def test_add_new_related(self): 71 with login(self, 'root', '123'): 72 callback_name = 'dismissRelatedItemLookupPopup' 73 add_url = reverse('admin:admin_related_lookup_popup_relateditem_add') 74 75 # check correct rendering form 76 response = self.client.get("%s?_popup=1&_callback=%s" % (add_url, callback_name)) 77 self.assertEqual(response.status_code, 200) 78 self.assertContains(response, '<input type="hidden" name="_popup" value="1" />', 1, 200) 79 self.assertContains(response, '<input type="hidden" name="_callback" value="%s" />' % callback_name, 1, 200) 80 81 # check correct posting form 82 response = self.client.post(add_url, { 83 'title': 'zxc', 84 '_popup': 1, 85 '_callback': callback_name, 86 }) 87 self.assertEqual(response.status_code, 200) 88 self.assertContains(response, '<script') 89 self.assertContains(response, callback_name) 90 91 92 def test_choose_new_from_changelist(self): 93 with login(self, 'root', '123'): 94 callback_name = 'dismissRelatedItemLookupPopup' 95 changelist_url = reverse('admin:admin_related_lookup_popup_relateditem_changelist') 96 97 response = self.client.get("%s?%s=1" % (changelist_url, IS_POPUP_VAR)) 98 self.assertContains(response, '"add/?_popup=1"', 1, 200) 99 100 response = self.client.get("%s?%s=1&%s=%s" % \ 101 (changelist_url, IS_POPUP_VAR, POPUP_CALLBACK_VAR, callback_name)) 102 self.assertContains(response, '"add/?_popup=1&_callback=%s"' % callback_name, 1, 200) 103 -
tests/regressiontests/admin_related_lookup_popup/models.py
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) -
django/contrib/admin/options.py
742 742 self.message_user(request, msg + ' ' + _("You may edit it again below.")) 743 743 if "_popup" in request.POST: 744 744 post_url_continue += "?_popup=1" 745 if '_callback' in request.REQUEST: 746 post_url_continue += '&_callback=%s' % request.REQUEST.get('_callback') 745 747 return HttpResponseRedirect(post_url_continue % pk_value) 746 748 747 749 if "_popup" in request.POST: 748 return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \ 750 action = request.REQUEST.get('_callback', 'dismissAddAnotherPopup') 751 return HttpResponse('<script type="text/javascript">opener.%s(window, "%s", "%s");</script>' % \ 749 752 # escape() calls force_unicode. 750 ( escape(pk_value), escapejs(obj)))753 (action, escape(pk_value), escapejs(obj))) 751 754 elif "_addanother" in request.POST: 752 755 self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 753 756 return HttpResponseRedirect(request.path) … … 957 960 'root_path': self.admin_site.root_path, 958 961 'app_label': opts.app_label, 959 962 } 963 if '_callback' in request.REQUEST: 964 context.update({'popup_callback': request.REQUEST.get('_callback')}) 960 965 context.update(extra_context or {}) 961 966 return self.render_change_form(request, context, form_url=form_url, add=True) 962 967 … … 1187 1192 'selection_note_all': selection_note_all % {'total_count': cl.result_count}, 1188 1193 'title': cl.title, 1189 1194 'is_popup': cl.is_popup, 1195 'popup_callback': cl.popup_callback, 1190 1196 'cl': cl, 1191 1197 'media': media, 1192 1198 'has_add_permission': self.has_add_permission(request), -
django/contrib/admin/templatetags/admin_list.py
216 216 value = result.serializable_value(attr) 217 217 result_id = repr(force_unicode(value))[1:] 218 218 yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \ 219 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener. dismissRelatedLookupPopup(window, %s); return false;"' % result_idor ''), conditional_escape(result_repr), table_tag))219 (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.%s(window, %s); return false;"' % (cl.get_popup_callback(), result_id) or ''), conditional_escape(result_repr), table_tag)) 220 220 else: 221 221 # By default the fields come from ModelAdmin.list_editable, but if we pull 222 222 # the fields out of the form instead of list_editable custom admins -
django/contrib/admin/views/main.py
24 24 SEARCH_VAR = 'q' 25 25 TO_FIELD_VAR = 't' 26 26 IS_POPUP_VAR = 'pop' 27 POPUP_CALLBACK_VAR = '_callback' 28 POPUP_CALLBACK_DEFAULT = 'dismissRelatedLookupPopup' 27 29 ERROR_FLAG = 'e' 28 30 29 31 IGNORED_PARAMS = ( 30 ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, TO_FIELD_VAR) 32 ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, \ 33 IS_POPUP_VAR, TO_FIELD_VAR, POPUP_CALLBACK_VAR 34 ) 31 35 32 36 # Text to display within change-list table cells if the value is blank. 33 37 EMPTY_CHANGELIST_VALUE = ugettext_lazy('(None)') … … 65 69 self.page_num = 0 66 70 self.show_all = ALL_VAR in request.GET 67 71 self.is_popup = IS_POPUP_VAR in request.GET 72 self.popup_callback = request.REQUEST.get(POPUP_CALLBACK_VAR) 68 73 self.to_field = request.GET.get(TO_FIELD_VAR) 69 74 self.params = dict(request.GET.items()) 70 75 if PAGE_VAR in self.params: … … 378 383 379 384 def url_for_result(self, result): 380 385 return "%s/" % quote(getattr(result, self.pk_attname)) 386 387 def get_popup_callback(self): 388 if self.popup_callback is not None: 389 return self.popup_callback 390 return POPUP_CALLBACK_DEFAULT -
django/contrib/admin/templates/admin/change_list.html
60 60 <ul class="object-tools"> 61 61 {% block object-tools-items %} 62 62 <li> 63 <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">63 <a href="add/{% if is_popup %}?_popup=1{% if popup_callback %}&_callback={{ popup_callback }}{% endif %}{% endif %}" class="addlink"> 64 64 {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %} 65 65 </a> 66 66 </li> -
django/contrib/admin/templates/admin/change_form.html
36 36 {% endblock %} 37 37 <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 %} 38 38 <div> 39 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}39 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% if popup_callback %}<input type="hidden" name="_callback" value="{{ popup_callback }}" />{% endif %}{% endif %} 40 40 {% if save_on_top %}{% submit_row %}{% endif %} 41 41 {% if errors %} 42 42 <p class="errornote">