I am trying to create a first implementation with django-rules, following the guidelines in the README.
To start with some basic concepts, I want to restrict deletion of a record to the record owner onlyin my app contact
. I managed (it seems) to get things working with my API provided via Django REST Framework. However, when I open Django Admin with a non-superuser user, I get the following error:
AttributeError: 'NoneType' object has no attribute 'created_by'
This appears to be related to my predicate definition in contact/rules.py
(I tried to follow the "book example" in the django-rules documentation here):
import rules
@rules.predicate
def is_contact_owner(user, contact):
return contact.created_by == user
@rules.predicate
def is_address_owner(user, address):
return address.created_by == user
rules.add_perm("contact.view_contact", rules.is_staff)
rules.add_perm("contact.add_contact", rules.is_staff)
rules.add_perm("contact.change_contact", rules.is_staff)
rules.add_perm("contact.delete_contact", is_contact_owner)
rules.add_perm("contact.view_address", rules.is_staff)
rules.add_perm("contact.add_address", rules.is_staff)
rules.add_perm("contact.change_address", rules.is_staff)
rules.add_perm("contact.delete_address", is_address_owner)
My contact/admin.py
looks as follows:
from django.contrib import admin
from rules.contrib.admin import ObjectPermissionsModelAdmin
# Register your models here.
from .models import Address, Contact
@admin.register(Address)
class AddressAdmin(ObjectPermissionsModelAdmin):
# class AddressAdmin(admin.ModelAdmin):
list_display = (
"id",
"local_address",
"country",
"uuid",
"created",
"modified",
"created_by",
"modified_by",
)
date_hierarchy = "created"
list_filter = ["created", "modified", "country"]
@admin.register(Contact)
class ContactAdmin(ObjectPermissionsModelAdmin):
# class ContactAdmin(admin.ModelAdmin):
list_display = (
"id",
"last_name",
"first_name",
"date_of_birth",
"uuid",
"created",
"modified",
"created_by",
"modified_by",
)
date_hierarchy = "created"
list_filter = ["created", "modified"]
Can anyone give me pointers as to what may be failing here?
So after adding some logging, I found out that my predicate function appears to be executed on every request, even when only the view permission should be checked. The error was observed on the admin login page, where no object for which I wanted to check the created_by
property was in the context yet.
This leads to another question: why is the predicate checked on every request? -> new post