Django Rest Framework Ordering Filter,按嵌套列表长度排序

时间:2016-09-15 08:17:06

标签: django django-rest-framework django-filter

我通过OrderingFilter全局使用settings.py,效果很好。

现在我想根据ManyToManyField的嵌套列表的大小来订购。这可能是默认的OrderingFilter吗?

如果没有,我是否可以使用自定义过滤器执行此操作,同时将查询参数ordering保留在网址(http://example.com/recipes/?ordering=)中。为了保持一致。

哦,ManyToManyField是一个表格。

这些是我的models.py

class Recipe(models.Model):
    name = models.CharField(max_length=255)
    cook_time = models.FloatField()
    ingredients = models.ManyToManyField(IngredientTag, through=Ingredient)

我的serializers.py

class IngredientTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = IngredientTag
        fields = ('id', 'label')

class IngredientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ingredient
        fields = ('amount', 'unit', 'ingredient_tag')
        depth = 1

class RecipeSerializer(serializers.ModelSerializer):
    ingredients = IngredientSerializer(source='ingredient_set', many=True)

    class Meta:
        model = Recipe
        fields = ('id', 'url', 'name', 'ingredients', 'cook_time')
        read_only_fields = ('owner',)
        depth = 2

我的views.py

class RecipeViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows recipes to be viewed or edited.
    """
    queryset = Recipe.objects.all().order_by()
    serializer_class = RecipeSerializer
    permission_classes = (DRYPermissions,)
    ordering_fields = ('cook_time',) #Need ingredient count somewhere?

谢谢!

1 个答案:

答案 0 :(得分:0)

尝试:

class RecipeSerializer(serializers.ModelSerializer):
    ingredients = IngredientSerializer(source='ingredient_set', many=True)
    ingredients_length = serializers.SerializerMethodField()

    class Meta:
        model = Recipe
        fields = ('id', 'url', 'name', 'ingredients', 'cook_time')
        read_only_fields = ('owner',)
        depth = 2

    def get_ingredients_length(self, obj):
        return obj.ingredients.count()

然后按ingredients_length订购

修改

在model.py中,尝试this

@property
    def ingredient_length(self):
        return self.ingredient_set.count()