I have a Django app that uses django-organizations
for supporting shared accounts, and rest_framework
for an API. I have a custom model for authentication that relates the user to an API token specific to an organization.
I have a model with a few foreign keys, a serializer with related fields, and a ModelViewSet for the API views. I want to make sure that any API calls for creating or modifying instances of my model verify that the objects specified for the related fields have the same owner (organization).
class Bar(models.Model):
uuid = models.UUIDField(
default=uuid.uuid4, editable=False, unique=True)
organization = models.ForeignKey(
Organization, on_delete=models.CASCADE)
class Foo(models.Model):
uuid = models.UUIDField(
default=uuid.uuid4, editable=False, unique=True)
organization = models.ForeignKey(
Organization, on_delete=models.CASCADE)
bar = models.ForeignKey(
Bar, on_delete=models.CASCADE)
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
fields = ('uuid', 'organization', 'bar')
bar = serializers.SlugRelatedField(
slug_field='uuid', queryset=Bar.objects.all())
How can I verify that related objects belong to the same account? Ideally, I'd be able to override the queryset specified for each RelatedField
in the serializer, but I don't think that's possible.
Two ways come to mind - you can do w/validation on the ModelSerializer, but you would have to then pass the request into a serializer. My gut says it probably makes more sense on the Viewset. That way, if it's accessing something that it shouldn't have access to it returns a 404 (less information leakage).
To have this on the viewset, define get_queryset w/
def get_queryset(self)
qs = MODEL.objects.filter(relation__user=self.request.user)
return qs
More examples below :