Code

Changes between Version 185 and Version 186 of BackwardsIncompatibleChanges


Ignore:
Timestamp:
07/18/08 17:13:20 (6 years ago)
Author:
brosner
Comment:

added a bit too much from nfa wiki page.

Legend:

Unmodified
Added
Removed
Modified
  • BackwardsIncompatibleChanges

    v185 v186  
    685685As of [7967] we have merged newforms-admin into trunk. Here is list of things that have changed: 
    686686 
    687 {{{ 
    688 #!python 
    689  
    690 # OLD: 
    691 from django.conf.urls.defaults import * 
    692  
    693 urlpatterns = patterns('', 
    694     (r'^admin/', include('django.contrib.admin.urls')), 
    695 ) 
    696  
    697 # NEW: 
    698 from django.conf.urls.defaults import * 
    699 from django.contrib import admin 
    700  
    701 admin.autodiscover() 
    702  
    703 urlpatterns = patterns('', 
    704     (r'^admin/(.*)', admin.site.root), 
    705 ) 
    706 }}} 
    707  
    708 Note that, in this above URLconf example, we're dealing with the object {{{django.contrib.admin.site}}}. This is an instance of {{{django.contrib.admin.AdminSite}}}, which is a class that lets you specify admin-site functionality. The object {{{django.contrib.admin.site}}} is a default {{{AdminSite}}} instance that is created for you automatically, but you can also create other instances as you see fit. 
    709  
    710 We use the {{{admin.autodiscover()}}} call above to force the import of the {{{admin.py}}} module of each {{{INSTALLED_APPS}}} entry. This won't be needed if you use your own {{{AdminSite}}} instance since you will likely be importing those modules explicily in a project-level {{{admin.py}}}. This was added in [7872]. 
    711  
    712 Previously, there was one "global" version of the admin site, which used all models that contained a {{{class Admin}}}. This new scheme allows for much more fine-grained control over your admin sites, allowing you to have multiple admin sites in the same Django instance. 
    713  
    714 In this example, we create two {{{AdminSite}}} instances, registering different models with both. Assume {{{Book}}}, {{{Author}}}, {{{Musician}}} and {{{Instrument}}} are Django model classes (not instances). 
    715  
    716 {{{ 
    717 #!python 
    718  
    719 # project-level admin.py 
    720  
    721 from django.contrib import admin 
    722 from myproject.myapp.models import Book, Author 
    723 from myproject.anotherapp.models import Musician, Instrument 
    724  
    725 site1 = admin.AdminSite() 
    726 site1.register(Book) 
    727 site1.register(Author) 
    728  
    729 site2 = admin.AdminSite() 
    730 site2.register(Musician) 
    731 site2.register(Instrument) 
    732  
    733 # URLconf 
    734  
    735 from django.conf.urls.defaults import * 
    736 from myproject.admin import site1, site2 
    737  
    738 urlpatterns = patterns('', 
    739     (r'^book_admin/(.*)', site1.root), 
    740     (r'^music_admin/(.*)', site2.root), 
    741 ) 
    742 }}} 
    743  
    744 With this example, if you go to {{{/book_admin/}}}, you'll get a Django admin site for the {{{Book}}} and {{{Author}}} models. If you go to {{{/music_admin/}}}, you'll get a Django admin site for the {{{Musician}}} and {{{Instrument}}} models. 
    745  
    746 Admin options -- the inner {{{class Admin}}} -- have changed, too. Models no longer use an inner class to declare their admin site options. In fact, '''all admin functionality has been decoupled from the model syntax'''! How, then, do we declare admin options? Like this: 
    747  
    748 {{{ 
    749 #!python 
    750 # a sample models.py file 
    751 from django.db import models 
    752  
    753 class Author(models.Model): 
    754     first_name = models.CharField(max_length=30) 
    755     last_name = models.CharField(max_length=30) 
    756  
    757     def __unicode__(self): 
    758         return u'%s %s' % (self.first_name, self.last_name) 
    759  
    760 class Book(models.Model): 
    761     title = models.CharField(max_length=100) 
    762     author = models.ForeignKey(Author) 
    763  
    764 # a sample admin.py file (in same app) 
    765 from django.contrib import admin 
    766 from myproject.myapp.models import Author, Book 
    767  
    768 class BookAdmin(admin.ModelAdmin): 
    769     list_display = ('title', 'author') 
    770     ordering = ('title',) 
    771  
    772 admin.site.register(Author) 
    773 admin.site.register(Book, BookAdmin) 
    774 }}} 
    775  
    776 In this example, we register both {{{Author}}} and {{{Book}}} with the {{{AdminSite}}} instance {{{django.contrib.admin.site}}}. {{{Author}}} doesn't need any custom admin options, so we just call {{{admin.site.register(Author)}}}. {{{Book}}}, on the other hand, has some custom admin options, so we define a {{{BookAdmin}}} class and pass that class as a second argument to {{{admin.site.register()}}}. 
    777  
    778 You'll notice the {{{BookAdmin}}} class looks a lot like the old-style {{{class Admin}}}. Almost all of the old {{{class Admin}}} options work exactly the same, with one or two exceptions. (For the options that have changed, we've made them '''much''' more powerful.) In addition to the classic options such as {{{list_display}}} and {{{ordering}}}, the {{{ModelAdmin}}} class introduces a wealth of extra hooks you can use to customize the admin site for that particular model. For example: 
    779  
    780 {{{ 
    781 #!python 
    782  
    783 class BookAdmin(admin.ModelAdmin): 
    784     list_display = ('title', 'author') 
    785     ordering = ('title',) 
    786  
    787     def has_change_permission(self, request, obj=None): 
    788         """ 
    789         John can only edit books by Roald Dahl. 
    790         """ 
    791         if obj and request.user.username == 'john': 
    792             return obj.author.last_name == 'Dahl' 
    793         return super(BookAdmin, self).has_change_permission(request, obj) 
    794 }}} 
    795  
    796 Look at the class {{{ModelAdmin}}} in the file [source:/django/branches/newforms-admin/django/contrib/admin/options.py django/contrib/admin/options.py] to see all of the methods you can override. This is exciting stuff. 
    797  
    798 == To-do list == 
    799  
    800   * See [http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&keywords=%7Enfa-blocker&order=priority list of tickets] blocking the merge to trunk. 
    801   * See [http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&keywords=%7Enfa-someday&order=priority list of tickets] that will be looked at after a merge to trunk. 
    802   * See [http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&status=closed&keywords=%7Enfa-fixed&order=priority list of tickets] that have been fixed. 
    803  
    804 == Backwards-incompatible changes == 
    805  
    806 This is a (currently incomplete) list of backwards-incompatible changes made in this branch. 
    807  
    808687=== Changed Admin.manager option to more flexible hook === 
    809688