I have a model Application
that has fields applicant = ForeignKey('User'...)
and coapplicant = ForeignKey('User'...)
.
There is also a model Income
that has field user = ForeignKey('User'...
.
I want to allow User A to create, edit, delete Income
objects of User B if A and B are in a relationship through Application
.
That means:
User A can CRUD Incomes of User B and vice-versa if there is such Application
object where A
is an applicant and B
co-applicant or A
is a co-applicant and B
applicant.
Do you know how to make that work?
CodePudding user response:
You can write custom permission something like this:
from django.db.models import F
class IsOwnerOrCoapplicant(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
if obj.user == request.user:
return True
# If application with both users exists return true,
# exclude cases when applicant and coapplicant are the same just in case
if Application.objects.filter(applicant__in=[obj.user, request.user], coapplicant__in=[obj.user, request.user]).exclude(applicant=F('coapplicant')).exists()
return True
return False
CodePudding user response:
you can define a many-to-many relationship between User A and other Users like B (which I am going to call coapplicants from now) using the Application
model. and Django through fields
for example:
from Django import models
class User(models.Model):
...
....
coapplicants = models.ManyToManyField(
'User',
through='Application',
through_fields=('applicant', 'coapplicant'),
)
class Application(models.Model):
applicant= models.ForeignKey('User',...)
coapplicant = models.ForeignKey('User'...)
if you want both A and B to be in this relationship, otherwise just use one of applicant
or coapplicant
in through_fields
. check documentation here
now that you defined a relationship between them, you can use Django rest object permissions to give User B access to edit Income
objects belonging to User A
. documentation here
from rest_framework import permissions
class IsOwnerOrCoapplicant(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# assuming Income instance has an attribute named `owner`.
return obj.owner == request.user or request.user.coapplicants.filter(id=obj.owner.id).exists()
if you add this permission to a ViewSet
that works with Income
objects, obj
argument passed to has_object_permission
function is an Income
instance.