Корректный способ структурирования моделей, представлений и сериализаторов

У меня есть следующая структура моделей Parent и Child, где ребенок ссылается на родителя.

class ParentModel(models.Model):
    name = models.CharField(max_length=255)


class ChildModel(models.Model):
    name = models.CharField(max_length=255)
    parent = models.ForeignKey(
        ParentModel, related_name='children', on_delete=models.CASCADE
    )
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)


class ParentSerializer(serializers.ModelSerializer):
    class Meta:
        model = ParentModel
        fields = (
            'name',
            'children',
        )


class ChildSerializer(serializers.ModelSerializer):
    class Meta:
        models = ChildModel
        fields = (
            'name'
        )


class ParentViewSet(viewsets.ModelViewSet):
    serializer_class = ParentSerializer
    queryset = ParentModel.objects.all()


class ChildViewSet(viewsets.ModelViewSet):
    serializer_class = ChildSerializer

    def get_queryset(self):
        user = self.request.user
        return ChildModel.objects.filter(created_by=user)

Я хотел бы, чтобы ParentSerializer.children включал только объекты ChildModel с created_by в качестве self.request.user.

Какой правильный способ фильтрации ParentSerializer.children для текущего пользователя?

Я также открыт для изменения моделей.

Сначала я думаю, что у вас есть проблема n+1 в вашем коде.
Когда DRF будет сериализовать ParentModel, обращение к current_parent.children.all() будет производить SQL запрос для каждого родителя.
Чтобы предотвратить это, вы можете использовать prefetch_related

class ParentViewSet(viewsets.ModelViewSet):
    serializer_class = ParentSerializer
    queryset = ParentModel.objects.prefetch_related(Prefetch("children"))

В результате будет выполнено 2 SQL-запроса вместо N+1 (где N - количество строк ParentModel).

Дополнительно вы можете использовать prefetch_related для фильтрации связанной модели:

class ParentViewSet(viewsets.ModelViewSet):
    serializer_class = ParentSerializer

    def get_queryset(self):
        user = self.request.user
        return ParentModel.objects.prefetch_related(Prefetch("children", queryset=ChildrenModel.objects.filter(created_by=user)))

Это то, что вы ищете, я думаю

Вернуться на верх