Multiple ModelAdmins/views for same model in Django admin
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Horror Game Menu Looping
--
Chapters
00:00 Question
02:13 Accepted answer (Score 346)
03:25 Answer 2 (Score 3)
03:48 Answer 3 (Score 2)
04:37 Thank you
--
Full question
https://stackoverflow.com/questions/2223...
Accepted answer links:
http://code.djangoproject.com/wiki/Dynam...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #djangoadmin
#avk47
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Horror Game Menu Looping
--
Chapters
00:00 Question
02:13 Accepted answer (Score 346)
03:25 Answer 2 (Score 3)
03:48 Answer 3 (Score 2)
04:37 Thank you
--
Full question
https://stackoverflow.com/questions/2223...
Accepted answer links:
http://code.djangoproject.com/wiki/Dynam...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #djangoadmin
#avk47
ACCEPTED ANSWER
Score 364
I've found one way to achieve what I want, by using proxy models to get around the fact that each model may be registered only once.
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'pubdate','user')
class MyPost(Post):
class Meta:
proxy = True
class MyPostAdmin(PostAdmin):
def get_queryset(self, request):
return self.model.objects.filter(user = request.user)
admin.site.register(Post, PostAdmin)
admin.site.register(MyPost, MyPostAdmin)
Then the default PostAdmin would be accessible at /admin/myapp/post and the list of posts owned by the user would be at /admin/myapp/myposts.
After looking at http://code.djangoproject.com/wiki/DynamicModels, I've come up with the following function utility function to do the same thing:
def create_modeladmin(modeladmin, model, name = None):
class Meta:
proxy = True
app_label = model._meta.app_label
attrs = {'__module__': '', 'Meta': Meta}
newmodel = type(name, (model,), attrs)
admin.site.register(newmodel, modeladmin)
return modeladmin
This can be used as follows:
class MyPostAdmin(PostAdmin):
def get_queryset(self, request):
return self.model.objects.filter(user = request.user)
create_modeladmin(MyPostAdmin, name='my-posts', model=Post)
ANSWER 2
Score 3
Paul Stone answer is absolutely great! Just to add, for Django 1.4.5 I needed to inherit my custom class from admin.ModelAdmin
class MyPostAdmin(admin.ModelAdmin):
def queryset(self, request):
return self.model.objects.filter(id=1)
ANSWER 3
Score 2
Based on the correct answers, I monkeypatch the AdminSite class and add the method register_via_proxy to make the task easier.
import re
from django.contrib import admin
def _register_proxy(self, model, admin_class):
proxy_model = type(
admin_class.__name__, (model,), {
"__module__": re.sub(
r'(^.*?)(\.[^\.]+)$', r'\1.proxy', model.__module__
),
"Meta": type("Meta", tuple(), {
"proxy": True,
"app_label": model._meta.app_label
})
}
)
return self.register(proxy_model, admin_class)
admin.sites.AdminSite.register_via_proxy = _register_proxy
And to use is like:
site = admin.sites.AdminSite()
site.register_via_proxy(models.ModelType, AdminClass)