Package: django-genericadmin
A simple django app to make the lookup of generic models easier.InstallationTo install add it to yourINSTALLED_APPSsetting. There is no need
to runmanage.py syncdbbecausedjango-genericadmindoes not have
any models.INSTALLED_APPS=(...'genericadmin',...)If you are using the staticfiles app, then runmanage.py collectstaticand you should be good to go.If you don’t know what I’m talking about or your django version < 1.3,
then you should link or copygenericadmin/media/js/to your asset
directory and setGENERICADMIN_JSto a the relative destination of
your just copied files.UsageTo usedjango-genericadminyour model admin class must inherit fromGenericAdminModelAdmin.So a model admin likeclassNavBarEntryAdmin(admin.ModelAdmin):passadmin.site.register(NavBarEntry,NavBarEntryAdmin)becomesfromgenericadmin.adminimportGenericAdminModelAdminclassNavBarEntryAdmin(GenericAdminModelAdmin):passadmin.site.register(NavBarEntry,NavBarEntryAdmin)That’s it.Provided admin classesA short overview of the admin classes and their uses provided bydjango-genericadmin.GenericAdminModelAdmin— The admin for a standard Django model
that has at least one generic foreign relation.TabularInlineWithGenericandStackedInlineWithGeneric—
Normal inline admins for models that have a generic relation and are
edited inline.GenericTabularInlineandGenericStackedInline— Used to
provideTrue Polymorphic Relationships(see below) and generic
relations in the admin. Also see the Django docshere.Inline UsageTo usedjango-genericadminwith admin inlines, your models must
inherit fromGenericAdminModelAdminas described above:fromgenericadmin.adminimportGenericAdminModelAdminclassNavBarEntryAdmin(GenericAdminModelAdmin):passadmin.site.register(NavBarEntry,NavBarEntryAdmin)Additionally the inline classes must inherit from eitherStackedInlineWithGenericorTabularInlineWithGeneric:fromgenericadmin.adminimportGenericAdminModelAdmin,TabularInlineWithGenericclassPagesInline(TabularInlineWithGeneric):model=...classNavBarEntryAdmin(GenericAdminModelAdmin):inlines=[PagesInline,]...Note that you can’t mix and match. If you’re going to use a generic
inline, the class using it must inherit fromGenericAdminModelAdmin.Specifying which fields are handledIn most casesdjango-genericadminwill correctly figure out which
fields on your model are generic foreign keys and just do the right
thing. If you want to specify the fields yourself (Control your own
destiny and all that) you can use thegeneric_fk_fieldsattribute on
the admin class. Note that you can specify the fields on each admin
class for inline admins. So, for the above mentioned inline admin, you
would do it like so:classPagesInline(TabularInlineWithGeneric):model=AReallyCoolPagegeneric_fk_fields=[{'ct_field':<field_name_for_contenttype_fk>,'fk_field':<field_name_for_object_id>,}]If you want to use more then one field pair, you can just add more dicts
to the list.If you use thect_fieldandct_fk_fieldattributesdjango-genericadminwill always just ignore those fields and not even
try to use them.Blacklisting Content TypesSpecific content types can be removed from the content type select list.
Example:classNavBarEntryAdmin(GenericAdminModelAdmin):content_type_blacklist=('auth/group','auth/user',)Whitelisting Content TypesSpecific content types that can be display from the content type select
list. Example:classNavBarEntryAdmin(GenericAdminModelAdmin):content_type_whitelist=('auth/message',)Note that this only happens on the client; there is no enforcement of
the blacklist at the model level.Lookup parameters by Content TypeSupply extra lookup parameters per content type similar to how
limit_choices_to works with raw id fields. Example:classNavBarEntryAdmin(GenericAdminModelAdmin):content_type_lookups={'app.model':{'field':'value'}True Polymorphic Relationshipsdjango-genericadminalso provides a UI to easily manage a
particularly useful model that, when used as an inline on another model,
enables relations from any entry of any model to any other entry of any
other model. And, because it has a generic relationship moving in both
directions, it means it can be attached as an inlineto any modelwithout having to create unique, individual foreign keys for each model
you want to use it on.Here’s an example of a polymorphic model:fromdjango.dbimportmodelsfromdjango.contrib.contenttypes.modelsimportContentTypefromdjango.contrib.contenttypesimportgenericclassRelatedContent(models.Model):"""
    Relates any one entry to another entry irrespective of their individual models.
    """content_type=models.ForeignKey(ContentType)object_id=models.PositiveIntegerField()content_object=generic.GenericForeignKey('content_type','object_id')parent_content_type=models.ForeignKey(ContentType,related_name="parent_test_link")parent_object_id=models.PositiveIntegerField()parent_content_object=generic.GenericForeignKey('parent_content_type','parent_object_id')def__unicode__(self):return"%s:%s"%(self.content_type.name,self.content_object)And here’s how you’d set up your admin.py:fromwhateverapp.modelsimportRelatedContentfromgenericadmin.adminimportGenericAdminModelAdmin,GenericTabularInlineclassRelatedContentInline(GenericTabularInline):model=RelatedContentct_field='parent_content_type'# See below (1).ct_fk_field='parent_object_id'# See below (1).classWhateverModelAdmin(GenericAdminModelAdmin):# Super important! See below (2).content_type_whitelist=('app/model','app2/model2')# Add white/black lists on this classinlines=[RelatedContentInline,](1) By defaultct_fieldandct_fk_fieldwill default tocontent_typeandobject_idrespectively.ct_fieldandct_fk_fieldare used to create the parent link from the inline to
the model you are attaching it to (similar to how Django does this
attachment using foreign keys with more conventional inlines). You could
also leave this configuration out of your inline classes but, if you do
that, I encourage you to change the model attributes fromparent_content_type&parent_object_idtochild_content_type&child_object_id. I say this because, when it comes time to make
queries, you’ll want to know which direction you’re ‘traversing’ in.(2) Make sure that whatever the admin classes are utilizing these
inlines are subclasses ofGenericAdminModelAdminfromdjango-genericadminor else the handy-dandy javascript-utilizing
interface won’t work as intended.