Django REST Fram的私人和公共领域

2024-10-01 04:55:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要一个公共和私人食谱的列表,隐藏所有私人食谱,除非它是所有者的。我为此创建了一个管理器:

class RecipeManager(models.Manager):

    def public_recipes(self, *args, **kwargs):
        return super(RecipeManager, self).filter(private=False)

    def private_recipes(self, *args, **kwargs):
        user = kwargs.pop('user')
        return super(RecipeManager, self).filter(private=True, user=user)


class Recipe(models.Model):
    name = models.CharField(max_length=100)
    recipe = models.CharField(max_length=200)
    private = models.BooleanField(default=False)

你知道吗视图.py地址:

class RecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.all()
    serializer_class = RecipeSerializer
    permission_classes = (AllowAny,)

你知道吗序列化程序.py地址:

class RecipeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Recipe
        fields = ('id', 'name', 'recipe', 'total_ingredients')
        depth = 1

那么,我在哪里可以使用方法public_recipesprivate_recipes或者有更好的解决方案吗?你知道吗


Tags: selfreturnmodelsdefrecipeargs私人private
1条回答
网友
1楼 · 发布于 2024-10-01 04:55:29

首先,您可能希望将自定义管理器设置为配方模型的默认管理器,如下所示:

class RecipeManager(models.Manager):

    def public_recipes(self, *args, **kwargs):
        return super(RecipeManager, self).filter(private=False)

    def private_recipes(self, *args, **kwargs):
        user = kwargs.pop('user')
        return super(RecipeManager, self).filter(private=True, user=user)


class Recipe(models.Model):
    name = models.CharField(max_length=100)
    recipe = models.CharField(max_length=200)
    private = models.BooleanField(default=False)

    objects = RecipeManager()  # Make this manager the default manager

您可以重写视图上的get_queryset()方法来合并用户的私有和公共配方:

class RecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.all()
    serializer_class = RecipeSerializer
    permission_classes = (AllowAny,)

    def get_queryset(self):
        if self.request.user:
            private_recipes = Recipe.objects.private_recipes(user=self.request.user)
        else:
            private_recipes = Recipe.objects.none()

        public_recipes = Recipe.objects.public_recipes()

        final_recipes_list = private_recipes | public_recipes # Shorthand to merge two querysets
        return final_recipes_list

实际上,我建议考虑对公共和私有菜谱使用不同的视图集,即

class PublicRecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.public_recipes()

class PrivateRecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.filter(private=True)

    def get_queryset(self):
        if not self.request.user:
            raise AuthenticationFailed()

        queryset = super().get_queryset()
        return queryset.filter(user=self.request.user)

相关问题 更多 >