Maaatt
Maaatt

Reputation: 118

In the Django admin is it possible to separate models into sub-models based on groups?

I think this is easiest to understand as an example:

I have models Image and ImageType, where and image has exactly one type. The parameters in ImageType would regulate image size, thumbnail size, etc., as photo gallery images might display differently from, say, profile pictures.

I want profile images and gallery images to appear as separate models in the Django admin site. One option is to do something like this:

class ProfileImage (Image):
    pass

class GalleryImage (Image):
    pass

class ProfileImageAdmin (ImageAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return qs.filter(type='profile')

class GalleryImageAdmin (ImageAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return qs.filter(type='gallery')

admin.site.register(ProfileImage, ProfileImageAdmin)
admin.site.register(GalleryImage, GalleryImageAdmin)

But besides having redundant code, that completely defeats the purpose of having a database to organize these in the first place. Another option is to lose my Image and ImageType models and create separate almost-identical tables for each type (i.e. ProfileImage and GalleryImage), but that is even worse, since that would require users to have access to the config files, which to my mind nearly defeats the purpose of a CMS.

Is there any way I can do something like this?

admin.site.register(Image, ImageAdmin, group_by='type')

Alternatively, if this is impossible, does anybody have any suggestions for other ways I could tackle this? (For example, is there a way in python to dynamically create classes based on the database?)

Cheers! Matt

Upvotes: 3

Views: 2567

Answers (1)

Manoj Govindan
Manoj Govindan

Reputation: 74675

There is a way. This involves using a proxy model for one (or both) type of images. You can then add separate admins for the two. For e.g.

# models.py
class ProfileImage (Image):
    class Meta:
        proxy = True

class GalleryImage (Image):
    class Meta:
        proxy = True

This will avoid creating new tables. You'll still be storing all the data in the table corresponding to the Image model. You can then register two different admins for these proxies.

# admin.py
class ProfileImageAdmin (ImageAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return qs.filter(type='profile')

class GalleryImageAdmin (ImageAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return qs.filter(type='gallery')

admin.site.register(ProfileImage, ProfileImageAdmin)
admin.site.register(GalleryImage, GalleryImageAdmin)

Upvotes: 8

Related Questions