Multiple ModelAdmins/views for same model in Django admin
Creating Multiple ModelAdmins/Views for the Same Model in Django Admin
Are you facing the challenge of creating multiple ModelAdmins/views for the same model in Django Admin? Perhaps you want to customize the views differently and link them to different URLs. In this blog post, we will explore this common issue and provide easy solutions for you.
The Context
Let's consider a scenario where we have a Django model called "Posts". By default, the admin view of this model lists all Post objects. However, you may want to have multiple views/ModelAdmins of the same model, each serving a specific purpose. For example:
"/admin/myapp/post" to list all post objects
"/admin/myapp/myposts" to list posts belonging to the user
"/admin/myapp/draftpost" to list posts that have not yet been published.
Achieving this without putting everything into a single ModelAdmin class and writing your own 'urls' function can be tricky. Let's explore some solutions.
Solution 1: Create Separate ModelAdmin Classes
One way to achieve this is by creating separate ModelAdmin classes for each specific view and registering them accordingly. Here's an example:
class AllPostAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date')
class MyPostsAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date')
def get_queryset(self, request):
return super().get_queryset(request).filter(author=request.user)
class DraftPostAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date')
def get_queryset(self, request):
return super().get_queryset(request).filter(published=False)
admin.site.register(Post, AllPostAdmin)
admin.site.register(Post, MyPostsAdmin, 'myposts')
admin.site.register(Post, DraftPostAdmin, 'draftposts')
In this solution, we create separate ModelAdmin classes for each specific view. By specifying a unique name for each registration, we can differentiate them in the URL patterns of the Django admin.
Solution 2: Override ModelAdmin URLs
Another approach is to override the URLs of the ModelAdmin itself. Here's an example:
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date')
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('myposts/', self.admin_site.admin_view(self.my_posts_view)),
path('draftposts/', self.admin_site.admin_view(self.draft_posts_view)),
]
return my_urls + urls
def my_posts_view(self, request):
# Custom logic to display only user's posts
queryset = self.get_queryset(request).filter(author=request.user)
# Your view implementation goes here
def draft_posts_view(self, request):
# Custom logic to display only draft posts
queryset = self.get_queryset(request).filter(published=False)
# Your view implementation goes here
admin.site.register(Post, PostAdmin)
In this solution, we override the get_urls
method of the ModelAdmin class and add custom URLs for each specific view. Inside each view method, you can implement the logic to display the desired queryset.
Conclusion
There you have it! Two easy solutions to create multiple ModelAdmins/views for the same model in Django Admin. By following these approaches, you can customize the views differently and link them to different URLs, catering to your specific requirements.
Feel free to explore these solutions and choose the one that best suits your use case. Don't hesitate to share your thoughts or other alternative solutions in the comments below. Happy Django Admin customization!
🚀 Share your experience with multiple ModelAdmins/views in Django Admin! Have you faced this challenge before? How did you solve it? Let's discuss in the comments. 🗣️