Ticket #16260: related_lookup_popup.diff

File related_lookup_popup.diff, 11.7 KB (added by alekam, 4 years ago)
  • tests/regressiontests/admin_related_lookup_popup/tests.py

     
     1"""
     2This file demonstrates writing tests using the unittest module. These will pass
     3when you run "manage.py test".
     4
     5Replace this with more appropriate tests for your application.
     6"""
     7
     8from django.contrib.admin.views.main import IS_POPUP_VAR, POPUP_CALLBACK_VAR
     9from django.contrib.auth.models import User
     10from django.core.urlresolvers import reverse
     11from django.test import TestCase
     12from models import *
     13
     14
     15class 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
     31class 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

     
     1from django.db import models
     2from django.contrib import admin
     3
     4
     5__all__ = ['RelatedItem', 'AnotherRelatedItem']
     6
     7
     8class RelatedItem(models.Model):
     9    title = models.CharField(max_length=25, blank=True, null=True)
     10
     11    def __unicode__(self):
     12        return self.title
     13
     14class 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
     21admin.site.register(RelatedItem, None)
     22admin.site.register(AnotherRelatedItem, None)
  • django/contrib/admin/options.py

     
    742742            self.message_user(request, msg + ' ' + _("You may edit it again below."))
    743743            if "_popup" in request.POST:
    744744                post_url_continue += "?_popup=1"
     745                if '_callback' in request.REQUEST:
     746                    post_url_continue += '&_callback=%s' % request.REQUEST.get('_callback')
    745747            return HttpResponseRedirect(post_url_continue % pk_value)
    746748
    747749        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>' % \
    749752                # escape() calls force_unicode.
    750                 (escape(pk_value), escapejs(obj)))
     753                (action, escape(pk_value), escapejs(obj)))
    751754        elif "_addanother" in request.POST:
    752755            self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
    753756            return HttpResponseRedirect(request.path)
     
    957960            'root_path': self.admin_site.root_path,
    958961            'app_label': opts.app_label,
    959962        }
     963        if '_callback' in request.REQUEST:
     964            context.update({'popup_callback': request.REQUEST.get('_callback')})
    960965        context.update(extra_context or {})
    961966        return self.render_change_form(request, context, form_url=form_url, add=True)
    962967
     
    11871192            'selection_note_all': selection_note_all % {'total_count': cl.result_count},
    11881193            'title': cl.title,
    11891194            'is_popup': cl.is_popup,
     1195            'popup_callback': cl.popup_callback,
    11901196            'cl': cl,
    11911197            'media': media,
    11921198            'has_add_permission': self.has_add_permission(request),
  • django/contrib/admin/templatetags/admin_list.py

     
    216216            value = result.serializable_value(attr)
    217217            result_id = repr(force_unicode(value))[1:]
    218218            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_id or ''), 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))
    220220        else:
    221221            # By default the fields come from ModelAdmin.list_editable, but if we pull
    222222            # the fields out of the form instead of list_editable custom admins
  • django/contrib/admin/views/main.py

     
    2424SEARCH_VAR = 'q'
    2525TO_FIELD_VAR = 't'
    2626IS_POPUP_VAR = 'pop'
     27POPUP_CALLBACK_VAR = '_callback'
     28POPUP_CALLBACK_DEFAULT = 'dismissRelatedLookupPopup'
    2729ERROR_FLAG = 'e'
    2830
    2931IGNORED_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)
    3135
    3236# Text to display within change-list table cells if the value is blank.
    3337EMPTY_CHANGELIST_VALUE = ugettext_lazy('(None)')
     
    6569            self.page_num = 0
    6670        self.show_all = ALL_VAR in request.GET
    6771        self.is_popup = IS_POPUP_VAR in request.GET
     72        self.popup_callback = request.REQUEST.get(POPUP_CALLBACK_VAR)
    6873        self.to_field = request.GET.get(TO_FIELD_VAR)
    6974        self.params = dict(request.GET.items())
    7075        if PAGE_VAR in self.params:
     
    378383
    379384    def url_for_result(self, result):
    380385        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

     
    6060        <ul class="object-tools">
    6161          {% block object-tools-items %}
    6262            <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">
    6464                {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
    6565              </a>
    6666            </li>
  • django/contrib/admin/templates/admin/change_form.html

     
    3636{% endblock %}
    3737<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 %}
    3838<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 %}
    4040{% if save_on_top %}{% submit_row %}{% endif %}
    4141{% if errors %}
    4242    <p class="errornote">
Back to Top