Ticket #20331: 20331.diff

File 20331.diff, 5.7 KB (added by Edwin <django@…>, 2 years ago)
  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index b35f100..812a24f 100644
    a b from django.db.models.related import RelatedObject 
    2222from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
    2323from django.db.models.sql.constants import QUERY_TERMS
    2424from django.http import Http404, HttpResponse, HttpResponseRedirect
     25from django.http.response import HttpResponseBase
    2526from django.shortcuts import get_object_or_404
    2627from django.template.response import SimpleTemplateResponse, TemplateResponse
    2728from django.utils.decorators import method_decorator
    class ModelAdmin(BaseModelAdmin): 
    973974
    974975            response = func(self, request, queryset)
    975976
    976             # Actions may return an HttpResponse, which will be used as the
    977             # response from the POST. If not, we'll be a good little HTTP
    978             # citizen and redirect back to the changelist page.
    979             if isinstance(response, HttpResponse):
     977            # Actions may return an HttpResponse-like object, which will be
     978            # used as the response from the POST. If not, we'll be a good
     979            # little HTTP citizen and redirect back to the changelist page.
     980            if isinstance(response, HttpResponseBase):
    980981                return response
    981982            else:
    982983                return HttpResponseRedirect(request.get_full_path())
  • docs/releases/1.6.txt

    diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
    index 3e15f5b..3f6c453 100644
    a b Minor features 
    202202* Added ``BCryptSHA256PasswordHasher`` to resolve the password truncation issue
    203203  with bcrypt.
    204204
     205* :doc:`Admin action </ref/contrib/admin/actions>` can now return any response
     206  that is a subclass of ``HttpResponseBase``, including
     207  :class:`~django.http.StreamingHttpResponse`.
     208
    205209Backwards incompatible changes in 1.6
    206210=====================================
    207211
  • tests/admin_views/admin.py

    diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py
    index cc7585c..e1f2ef2 100644
    a b from django.core.mail import EmailMessage 
    1212from django.conf.urls import patterns, url
    1313from django.db import models
    1414from django.forms.models import BaseModelFormSet
    15 from django.http import HttpResponse
     15from django.http import HttpResponse, StreamingHttpResponse
    1616from django.contrib.admin import BooleanFieldListFilter
    1717
    1818from .models import (Article, Chapter, Account, Media, Child, Parent, Picture,
    def redirect_to(modeladmin, request, selected): 
    238238redirect_to.short_description = 'Redirect to (Awesome action)'
    239239
    240240
     241def download(modeladmin, request, selected):
     242    import StringIO
     243    from django.core.servers.basehttp import FileWrapper
     244    buf = StringIO.StringIO('This is the content of the file')
     245    return StreamingHttpResponse(FileWrapper(buf))
     246download.short_description = 'Download subscription'
     247
     248
     249def no_perm(modeladmin, request, selected):
     250    return HttpResponse(content='No permission to perform this action',
     251                        status=403)
     252no_perm.short_description = 'No permission to run'
     253
     254
    241255class ExternalSubscriberAdmin(admin.ModelAdmin):
    242     actions = [redirect_to, external_mail]
     256    actions = [redirect_to, external_mail, download, no_perm]
    243257
    244258
    245259class Podcast(Media):
  • tests/admin_views/tests.py

    diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
    index e0000ff..1c78b60 100644
    a b class AdminActionsTest(TestCase): 
    24132413        response = self.client.post(url, action_data)
    24142414        self.assertRedirects(response, url)
    24152415
     2416    def test_custom_function_action_streaming_response(self):
     2417        """Tests a custom action that returns a StreamingHttpResponse."""
     2418        action_data = {
     2419            ACTION_CHECKBOX_NAME: [1],
     2420            'action': 'download',
     2421            'index': 0,
     2422        }
     2423        response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data)
     2424        content = ''.join([b for b in response.streaming_content])
     2425        self.assertEqual(content, 'This is the content of the file')
     2426        self.assertEqual(response.status_code, 200)
     2427
     2428    def test_custom_function_action_no_perm_response(self):
     2429        """Tests a custom action that returns an HttpResponse with 403 code."""
     2430        action_data = {
     2431            ACTION_CHECKBOX_NAME: [1],
     2432            'action': 'no_perm',
     2433            'index': 0,
     2434        }
     2435        response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data)
     2436        self.assertEqual(response.status_code, 403)
     2437        self.assertEqual(response.content, 'No permission to perform this action')
     2438
    24162439    def test_actions_ordering(self):
    24172440        """
    24182441        Ensure that actions are ordered as expected.
    class AdminActionsTest(TestCase): 
    24212444        response = self.client.get('/test_admin/admin/admin_views/externalsubscriber/')
    24222445        self.assertContains(response, '''<label>Action: <select name="action">
    24232446<option value="" selected="selected">---------</option>
    2424 <option value="delete_selected">Delete selected external subscribers</option>
     2447<option value="delete_selected">Delete selected external
     2448subscribers</option>
    24252449<option value="redirect_to">Redirect to (Awesome action)</option>
    2426 <option value="external_mail">External mail (Another awesome action)</option>
     2450<option value="external_mail">External mail (Another awesome
     2451action)</option>
     2452<option value="download">Download subscription</option>
     2453<option value="no_perm">No permission to run</option>
    24272454</select>''', html=True)
    24282455
    24292456    def test_model_without_action(self):
Back to Top