如何在DRF中的Browsable API中针对当前用户过滤ManyToManyField?

时间:2018-05-09 18:52:39

标签: python django django-models django-rest-framework

我有2个模型,TodoTag。 Todo与Tag有许多关系。从Browsable API添加新的Todos时,我希望只能看到当前用户添加的标签作为multiselect中的可用选项。目前,它显示所有添加的标签,无论谁添加它们。我想限制选项只显示当前用户添加的标签。 (已经设置了身份验证)

模特:

class Todo(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    due_at = models.DateTimeField(blank=True)
    updated_at = models.DateTimeField(auto_now=True)

    tags = models.ManyToManyField(Tag, related_name='todos')

    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='todos')

class Tag(models.Model):
    name = models.CharField(max_length=20)
    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='created_tags')

    def __str__(self):
        return self.name

The Serializer:

class TodoCreateSerializer(serializers.ModelSerializer): #This is the one being used for a POST
    class Meta:
        model = models.Todo
        fields = ('title', 'description', 'due_at', 'tags')

是否有一些序列化程序字段或其他一些方法来指定在Serializer中使用哪个查询集?还有其他更好的方法吗?

1 个答案:

答案 0 :(得分:1)

TodoCreateSerializer中,您需要添加PrimaryKeyRelatedField个自定义queryset,其中包含用户的过滤标记。

首先,您需要创建一个自定义PrimaryKeyRelatedField来过滤任何对象,以便只获取用户拥有的对象。

class UserFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        request = self.context.get('request', None)
        queryset = super(UserFilteredPrimaryKeyRelatedField, self).get_queryset()
        if not request or not queryset:
            return None
        return queryset.filter(user=request.user)

(这是一个通用的,可以在user

中过滤对象时使用

然后你应该在TodoCreateSerializer中使用这个:

class TodoCreateSerializer(serializers.ModelSerializer): 
    tags = UserFilteredPrimaryKeyRelatedField(queryset= Tag.objects, many=True)

    class Meta:
        model = models.Todo
        fields = ('title', 'description', 'due_at', 'tags')