Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I register multiple Django ModelAdmin with same Model?

I have the following ModelAdmin:

class EventAdmin(admin.ModelAdmin):
    # ModelAdmin config

    def queryset(self, request):
        queryset = super(EventAdmin, self).queryset(request)
        return queryset.exclude(date_end__lt=date.today())

admin.site.register(Event, EventAdmin)

Now I want to add a model to manage archived (older than today) events.

class EventArchiveAdmin(admin.ModelAdmin):
    # ModelAdmin config

    def queryset(self, request):
        queryset = super(EventArchiveAdmin, self).queryset(request)
        return queryset.filter(date_end__lt=date.today())

admin.site.register(Event, EventArchiveAdmin)

But if I try to do so I get AlreadyRegistered exception.

Why can't I implement another ModelAdmin with same Model and how can I get different admin views of the same model?

I know I can implement a custom list_filter in my class but I'd like to keep things separated in different pages.

like image 952
Luca Avatar asked Oct 08 '12 22:10

Luca


1 Answers

Use proxy models:

class Event(db.Model):
     ...

class ActiveEventManager(models.Manager):
    def get_queryset(self):
        return super(ActiveEventManager, self).get_queryset().filter(active=True)

class ActiveEvent(Event):
    class Meta:
        proxy = True

    objects = ActiveEventManager()

class ArchiveEventManager(models.Manager):
    def get_queryset(self):
        return super(ArchiveEventManager, self).get_queryset().filter(active=False)


class ArchiveEvent(Event):
    class Meta:
        proxy = True

    objects = ArchiveEventManager()

Now, you can register 2 models without override ModelAdmin.queryset method:

class EventAdmin(admin.ModelAdmin):
    # ModelAdmin config

admin.site.register(ActiveEvent, EventAdmin)
admin.site.register(ArchiveEvent, EventAdmin)

You can read mode about proxy models and managers in the doc.

Also, use this:

queryset = super(EventArchiveAdmin, self).queryset(request)

As first argument super() take current class. See doc

Note: django has renamed Manager.get_query_set to Manager.get_queryset in django==1.7.

like image 170
defuz Avatar answered Sep 28 '22 08:09

defuz