我想要一个公共和私人食谱的列表,隐藏所有私有食谱,除非它是所有者的。我为此创建了一个经理:
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)
views.py:
class RecipeViewSet(viewsets.ModelViewSet):
queryset = Recipe.objects.all()
serializer_class = RecipeSerializer
permission_classes = (AllowAny,)
serializers.py:
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = ('id', 'name', 'recipe', 'total_ingredients')
depth = 1
那么,在哪里可以使用方法public_recipes
,private_recipes
,或者有更好的解决方案?
答案 0 :(得分:0)
首先,您可能希望将自定义管理器设置为配方模型的默认管理器,如下所示:
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
我实际上建议考虑为公共和私人食谱使用不同的ViewSet,即
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)