I can't prescribe permissions. I have Accounts, Sites and Informations models:
Accounts
class Accounts(models.Model):
user = models.ForeignKey(to=User, on_delete=models.SET_NULL, null=True, editable=True, blank=True, verbose_name='Пользователь')
name = models.CharField(max_length=255, unique=True, verbose_name='Название')
def __str__(self):
return self.name
Sites and Informations
class Sites(models.Model):
account = models.ForeignKey(to=Accounts, on_delete=models.RESTRICT)
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Information(models.Model):
site = models.ForeignKey(to=Sites, related_name='information', on_delete=models.RESTRICT)
name_of_data = models.CharField(max_length=255)
data = models.CharField(max_length=255)
def __str__(self):
return self.name_of_data
My view should return a list of sites and information for each site, depending on which account is requested (like /accounts/3 should return all sites and information that belong to the 3rd account). Here are my serializers for more understanding:
from .models import Information, Sites
from app.serializers import AccountsSerializer
class InformationSerializer(serializers.ModelSerializer):
class Meta:
model = Information
fields = ['name_of_data', 'data']
class SitesSerializer(serializers.ModelSerializer):
information = InformationSerializer(many=True, read_only=True)
account = AccountsSerializer(read_only=True)
class Meta:
model = Sites
fields = ['account', 'name', 'information']
Here is my view for this:
class ProfileView(ListAPIView):
def list(self, request, *args, **kwargs):
self.check_object_permissions()
account_id = self.kwargs.get('account_id')
queryset = Sites.objects.filter(account_id=account_id)
serializer = SitesSerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
I need to restrict user access using the following rule:
But I always get errors and always different errors.
In the above code Permissions is not checked at all and does not work.
First of all i think Accounts
instance should be on the top level, then Sites
, then Information
. So in my opinion you should rebuild your serializers.
Secondly, i dont think you need to fetch query params manually in this case - Try to use RetrieveAPIView
.
Technically, you dont need permissions for multiple objects. You check the rights to view the Accounts
instance, after which you show the Account
data and all data related to it (Sites
and Information
).
from rest_framework.serializers import ModelSerializer
class InformationSerializer(ModelSerializer):
class Meta:
model = Information
fields = ["name_of_data", "data"]
class SitesSerializer(ModelSerializer):
information = InformationSerializer(many=True, read_only=True)
class Meta:
model = Sites
fields = ["id", "information"]
class AccountsRetrieveSerializer(ModelSerializer):
sites = SitesSerializer(many=True, read_only=True)
class Meta:
model = Accounts
fields = ["id", "name", "sites"]
from rest_framework.permissions import BasePermission
class IsObjectOwner(BasePermission):
def has_object_permission(self, request, view, obj):
return obj.user == request.user
from rest_framework.generics import RetrieveAPIView
from rest_framework.permissions import IsAuthenticated
class ProfileView(RetrieveAPIView):
permission_classes = [IsAuthenticated, IsObjectOwner]
serializer_class = AccountsRetrieveSerializer
Hope it helped you a little.