【问题标题】:How can I filter a ManyToManyField against the current User in the Browsable API in DRF?如何在 DRF 的 Browsable API 中针对当前用户过滤 ManyToManyField?
【发布时间】:2018-05-09 18:52:38
【问题描述】:

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

模型:

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

序列化器:

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

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

【问题讨论】:

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


    【解决方案1】:

    在您的TodoCreateSerializer 中,您需要添加带有自定义querysetPrimaryKeyRelatedField,该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')
    

    【讨论】:

    • 建议将many=True 作为参数传递给UserFilteredPrimaryKeyRelatedField 以启用多选。目前它只允许您从下拉列表中选择一个标签。
    • @AamirKhan,哦,我错过了!已编辑。
    猜你喜欢
    • 2021-04-07
    • 2020-06-30
    • 1970-01-01
    • 2021-10-20
    • 2022-11-30
    • 2015-07-13
    • 2020-08-09
    • 1970-01-01
    • 2017-05-22
    相关资源
    最近更新 更多