Django

Code

Ticket #9749: patch_django_9749.20090318.diff

File patch_django_9749.20090318.diff, 8.3 kB (added by david, 1 year ago)

Just an update against r10087

  • django/contrib/admin/validation.py

    old new  
    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 
     
    149150                raise ImproperlyConfigured("'%s.inlines[%d].model' does not " 
    150151                        "inherit from models.Model." % (cls.__name__, idx)) 
    151152            validate_base(inline, inline.model) 
    152             validate_inline(inline
     153            validate_inline(inline, cls, model
    153154 
    154 def validate_inline(cls): 
     155    # changelist_class = ChangeList 
     156    if hasattr(cls, 'changelist_class') and not issubclass(cls.changelist_class, ChangeList): 
     157        raise ImproperlyConfigured("'%s.changelist_class' does not inherit " 
     158                        "from admin.views.main.ChangeList." % cls.__name__) 
     159 
     160def validate_inline(cls, parent, parent_model): 
    155161    # model is already verified to exist and be a Model 
    156162    if cls.fk_name: # default value is None 
    157163        f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name) 
  • django/contrib/admin/options.py

    old new  
    171171 
    172172class ModelAdmin(BaseModelAdmin): 
    173173    "Encapsulates all admin options and functionality for a given model." 
     174    # Avoid circular import of ChangeList 
     175    from django.contrib.admin.views.main import ChangeList 
     176     
    174177    __metaclass__ = forms.MediaDefiningClass 
    175178 
    176179    list_display = ('__str__',) 
     
    185188    save_on_top = False 
    186189    ordering = None 
    187190    inlines = [] 
    188  
     191    changelist_class = ChangeList 
     192     
    189193    # Custom templates (designed to be over-ridden in subclasses) 
    190194    change_form_template = None 
    191195    change_list_template = None 
     
    703707 
    704708    def changelist_view(self, request, extra_context=None): 
    705709        "The 'change list' admin view for this model." 
    706         from django.contrib.admin.views.main import ChangeList, ERROR_FLAG 
    707710        opts = self.model._meta 
    708711        app_label = opts.app_label 
    709712        if not self.has_change_permission(request, None): 
    710713            raise PermissionDenied 
    711714        try: 
    712             cl = ChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter, 
     715            cl = self.changelist_class(request, self.model, self.list_display, self.list_display_links, self.list_filter, 
    713716                self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self.list_editable, self) 
    714717        except IncorrectLookupParameters: 
    715718            # Wacky lookup parameters were given, so redirect to the main 
     
    717720            # parameter via the query string. If wacky parameters were given and 
    718721            # the 'invalid=1' parameter was already in the query string, something 
    719722            # is screwed up with the database, so display an error page. 
     723            from django.contrib.admin.views.main import ERROR_FLAG 
    720724            if ERROR_FLAG in request.GET.keys(): 
    721725                return render_to_response('admin/invalid_setup.html', {'title': _('Database error')}) 
    722726            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1') 
  • tests/regressiontests/admin_views/tests.py

    old new  
    875875        self.failUnlessEqual(FooAccount.objects.all()[0].username, "%s-1" % foo_user) 
    876876        self.failUnlessEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user) 
    877877        self.failUnlessEqual(Persona.objects.all()[0].accounts.count(), 2) 
     878 
     879 
     880class AdminCustomChangeListTest(TestCase): 
     881    fixtures = ['admin-views-users.xml'] 
     882 
     883    def setUp(self): 
     884        self.client.login(username='super', password='secret') 
     885 
     886    def tearDown(self): 
     887        self.client.logout() 
     888 
     889    def testCustomLinkPresence(self): 
     890        """ 
     891        A test to ensure that custom ChangeList class works as expected. 
     892        """ 
     893        post_data = { 
     894            "title": u"Lion", 
     895        } 
     896        response = self.client.post('/test_admin/admin/admin_views/animal/add/', post_data) 
     897        self.failUnlessEqual(response.status_code, 302) # redirect somewhere 
     898        response = self.client.get('/test_admin/admin/admin_views/animal/') 
     899        self.failUnlessEqual(response.status_code, 200) 
     900        should_contain = """<a href="custom/1/">Lion</a>""" 
     901        self.assertContains(response, should_contain) 
     902 
     903 
  • tests/regressiontests/admin_views/models.py

    old new  
    165166    def __unicode__(self): 
    166167        return self.name 
    167168 
     169class Animal(models.Model): 
     170    title = models.CharField(max_length=20) 
     171    def __unicode__(self): 
     172        return self.title 
     173 
     174class AnimalChangeList(admin.views.main.ChangeList): 
     175    def url_for_result(self, result): 
     176        return "custom/%s/" % admin.util.quote(getattr(result, self.pk_attname)) 
     177 
    168178class Account(models.Model): 
    169179    """ 
    170180    A simple, generic account encapsulating the information shared by all 
     
    199209        BarAccountAdmin 
    200210    ) 
    201211 
     212class AnimalAdmin(admin.ModelAdmin): 
     213    changelist_class = AnimalChangeList 
    202214 
     215 
    203216admin.site.register(Article, ArticleAdmin) 
    204217admin.site.register(CustomArticle, CustomArticleAdmin) 
    205218admin.site.register(Section, inlines=[ArticleInline]) 
     
    208221admin.site.register(Thing, ThingAdmin) 
    209222admin.site.register(Person, PersonAdmin) 
    210223admin.site.register(Persona, PersonaAdmin) 
     224admin.site.register(Animal, AnimalAdmin) 
    211225 
    212226# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. 
    213227# That way we cover all four cases: 
  • tests/regressiontests/modeladmin/models.py

    old new  
    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

    old new  
    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