Ticket #9749: patch_django_9749.20090111.2.diff

File patch_django_9749.20090111.2.diff, 7.9 KB (added by david, 6 years ago)

More tests, against r9728

  • django/contrib/admin/validation.py

     
    55
    66from django.core.exceptions import ImproperlyConfigured
    77from django.db import models
    88from django.forms.models import BaseModelForm, BaseModelFormSet, fields_for_model
    99from django.contrib.admin.options import flatten_fieldsets, BaseModelAdmin
    1010from django.contrib.admin.options import HORIZONTAL, VERTICAL
     11from django.contrib.admin.views.main import ChangeList
    1112
    1213__all__ = ['validate']
    1314
     
    117118                raise ImproperlyConfigured("'%s.inlines[%d].model' does not "
    118119                        "inherit from models.Model." % (cls.__name__, idx))
    119120            validate_base(inline, inline.model)
    120121            validate_inline(inline)
    121122
     123    # changelist_class = ChangeList
     124    if hasattr(cls, 'changelist_class') and not issubclass(cls.changelist_class, ChangeList):
     125        raise ImproperlyConfigured("'%s.changelist_class' does not inherit "
     126                        "from admin.views.main.ChangeList." % cls.__name__)
     127
    122128
    123129def validate_inline(cls):
    124130    # model is already verified to exist and be a Model
    125131    if cls.fk_name: # default value is None
  • django/contrib/admin/options.py

             f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
     
     
    153153
    154154class ModelAdmin(BaseModelAdmin):
    155155    "Encapsulates all admin options and functionality for a given model."
     156    # Avoid circular import of ChangeList
     157    from django.contrib.admin.views.main import ChangeList
     158   
    156159    __metaclass__ = forms.MediaDefiningClass
    157160
    158161    list_display = ('__str__',)
     
    166169    save_on_top = False
    167170    ordering = None
    168171    inlines = []
     172    changelist_class = ChangeList
    169173
    170174    # Custom templates (designed to be over-ridden in subclasses)
    171175    change_form_template = None
     
    620624
    621625    def changelist_view(self, request, extra_context=None):
    622626        "The 'change list' admin view for this model."
    623         from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
    624627        opts = self.model._meta
    625628        app_label = opts.app_label
    626629        if not self.has_change_permission(request, None):
    627630            raise PermissionDenied
    628631        try:
    629             cl = ChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter,
     632            cl = self.changelist_class(request, self.model, self.list_display, self.list_display_links, self.list_filter,
    630633                self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self)
    631634        except IncorrectLookupParameters:
    632635            # Wacky lookup parameters were given, so redirect to the main
     
    634637            # parameter via the query string. If wacky parameters were given and
    635638            # the 'invalid=1' parameter was already in the query string, something
    636639            # is screwed up with the database, so display an error page.
     640            from django.contrib.admin.views.main import ERROR_FLAG
    637641            if ERROR_FLAG in request.GET.keys():
    638642                return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
    639643            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
  • tests/regressiontests/admin_views/tests.py

     
    735735        self.failUnlessEqual(response.status_code, 200)
    736736        response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict)
    737737        self.assertRedirects(response, '/test_admin/admin/admin_views/book/')
     738
     739class AdminCustomChangeListTest(TestCase):
     740    fixtures = ['admin-views-users.xml']
     741
     742    def setUp(self):
     743        self.client.login(username='super', password='secret')
     744
     745    def tearDown(self):
     746        self.client.logout()
     747
     748    def testCustomLinkPresence(self):
     749        """
     750        A test to ensure that custom ChangeList class works as expected.
     751        """
     752        post_data = {
     753            "title": u"Lion",
     754        }
     755        response = self.client.post('/test_admin/admin/admin_views/animal/add/', post_data)
     756        self.failUnlessEqual(response.status_code, 302) # redirect somewhere
     757        response = self.client.get('/test_admin/admin/admin_views/animal/')
     758        self.failUnlessEqual(response.status_code, 200)
     759        should_contain = """<a href="custom/1/">Lion</a>"""
     760        self.assertContains(response, should_contain)
  • tests/regressiontests/admin_views/models.py

     
    134134class ThingAdmin(admin.ModelAdmin):
    135135    list_filter = ('color',)
    136136
     137class Animal(models.Model):
     138    title = models.CharField(max_length=20)
     139    def __unicode__(self):
     140        return self.title
     141
     142class AnimalChangeList(admin.views.main.ChangeList):
     143    def url_for_result(self, result):
     144        return "custom/%s/" % admin.util.quote(getattr(result, self.pk_attname))
     145
     146class AnimalAdmin(admin.ModelAdmin):
     147    changelist_class = AnimalChangeList
     148
    137149admin.site.register(Article, ArticleAdmin)
    138150admin.site.register(CustomArticle, CustomArticleAdmin)
    139151admin.site.register(Section, inlines=[ArticleInline])
    140152admin.site.register(ModelWithStringPrimaryKey)
    141153admin.site.register(Color)
    142154admin.site.register(Thing, ThingAdmin)
     155admin.site.register(Animal, AnimalAdmin)
    143156
    144157# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
    145158# That way we cover all four cases:
  • tests/regressiontests/modeladmin/models.py

     
    912912...     inlines = [ValidationTestInline]
    913913>>> validate(ValidationTestModelAdmin, ValidationTestModel)
    914914
     915# changelist_class
     916
     917>>> class ValidationTestModelAdmin(ModelAdmin):
     918...     changelist_class = object
     919>>> validate(ValidationTestModelAdmin, ValidationTestModel)
     920Traceback (most recent call last):
     921...
     922ImproperlyConfigured: 'ValidationTestModelAdmin.changelist_class' does not inherit from admin.views.main.ChangeList.
     923
     924>>> from django.contrib.admin.views.main import ChangeList
     925>>> class ValidationTestChangeList(ChangeList):
     926...     def url_for_result(self, result):
     927...         return "custom/%s/" % quote(getattr(result, self.pk_attname))
     928>>> class ValidationTestModelAdmin(ModelAdmin):
     929...     changelist_class = ValidationTestChangeList
     930>>> validate(ValidationTestModelAdmin, ValidationTestModel)
     931
    915932"""
    916933}
  • docs/ref/contrib/admin.txt

     
    7777    class AuthorAdmin(admin.ModelAdmin):
    7878        date_hierarchy = 'pub_date'
    7979
     80``changelist_class``
     81~~~~~~~~~~~~~~~~~~
     82
     83Set ``changelist_class`` to a class which inherits from
     84``admin.views.main.ChangeList``, and the change list page will use this class
     85to render the list.
     86
     87Example::
     88
     89    from django.contrib import admin
     90   
     91    class CustomChangeList(admin.views.main.ChangeList):
     92        def url_for_result(self, result):
     93            return "custom/%s/" % admin.util.quote(getattr(result, self.pk_attname))
     94   
     95    class AuthorAdmin(admin.ModelAdmin):
     96        date_hierarchy = 'pub_date'
     97        changelist_class = CustomChangeList
     98   
     99
    80100``date_hierarchy``
    81101~~~~~~~~~~~~~~~~~~
    82102
Back to Top