For some reason, has_change_permission on an inline model admin passes the parent object as obj. A quick Google search has an AI snippet that suggests an inline_obj argument exists for has_change_permission, although it seems it does not based on the code and documentation. This seems like a perfectly reasonable solution, so I’m proposing it, even if it’s an AI hallucination. The problem I am trying to solve is determining permission to edit based on the inline object being rendered rather than the parent object. Some inline objects should be editable, and some should not.
Here is information about has_change_permission in Django’s InlineModelAdmin.
The has_change_permission method in InlineModelAdmin controls whether a user has permission to change an existing related object through an inline form on the parent model’s change page. By default, it inherits the permission logic from the model admin of the related model. However, you can override this method to customize the permission check for inline objects.
To customize the change permission for inline objects, you can override the has_change_permission method within your InlineModelAdmin class. This method accepts the request, the parent object (obj), and optionally the inline object (inline_obj) as arguments. You can implement your custom logic based on these arguments to determine whether the user has permission to change the inline object.
from django.contrib import admin
class MyInline(admin.TabularInline):
model = MyModel # Replace MyModel with your actual inline model
def has_change_permission(self, request, obj=None, inline_obj=None):
if not inline_obj:
# If inline_obj is None, it means we are checking for permission to add a new inline
return True # Or your custom logic for adding new inlines
# Custom logic to check if the user has permission to change this specific inline_obj
if request.user.is_superuser or inline_obj.user == request.user:
return True
return False