Restricting Object Visibility and Querysets
Explore how to restrict object visibility in Django admin by overriding get_queryset, securing foreign key dropdowns, and enforcing object-level permissions. This lesson teaches you to control data access based on user roles, preventing unauthorized views and edits by combining query filters and permission overrides.
We'll cover the following...
In the previous lesson, we established a scalable authorization architecture using groups and standard permissions. While these native permissions are powerful, they are fundamentally broad. They operate entirely at the table level. If you assign a user the change_choice permission, they gain the ability to edit every single choice record in the database. When business rules dictate that specific users should only interact with a limited subset of data, we must move beyond table-level toggles and implement object-level restrictions.
The limits of table-level permissions
Imagine a scenario where we employ external contractors to write quiz choices. We map them to an “External Writers” group and grant them the view_choice and change_choice permissions. However, our business rules explicitly state that external writers are only authorized to manage choices for questions written by a specific internal author (for example, the author with an ID of 1).
The standard Django permission matrix cannot handle this requirement natively. To enforce this, we must intercept the data pipeline at three distinct interaction points: the changelist data table, the relationship dropdowns on the form, and the direct URL access layer.
Filtering the changelist with get_queryset
The first step in restricting object visibility is filtering the rows displayed on the main changelist page. Whenever a user navigates to a model’s list view, Django calls the get_queryset() method inside the corresponding ModelAdmin class to fetch the database records.
By overriding this ...