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.

1

There are 1 best solutions below

0
On BEST ANSWER

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 :

https://docs.djangoproject.com/en/2.1/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_queryset