【问题标题】:Django Rest Framework Ordering Filter, order by nested list lengthDjango Rest Framework 排序过滤器,按嵌套列表长度排序
【发布时间】:2017-01-23 04:32:52
【问题描述】:

我通过settings.py 在全球范围内使用OrderingFilter,效果很好。

现在我想从ManyToManyField 订购嵌套列表的大小。使用默认的OrderingFilter 可以吗?

如果没有,有没有办法我可以使用自定义过滤器来做到这一点,同时将查询参数 ordering 保留在 url (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?

谢谢!

【问题讨论】:

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


    【解决方案1】:

    试试:

    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()
    

    然后按成分长度排序

    编辑

    在model.py中,试试this:

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

    【讨论】:

    • 首先你不能在 obj.ingredients 上使用len。你必须使用 obj.ingredients.all() 什么的,对吧?二是行不通。我得到一个FieldError: Cannot resolve keyword u'ingredients_length' into field. 我想我在某处读到 OrderingFilter 在数据库级别上工作,所以 python 计算字段不起作用?
    • 感谢您的帮助。在这两种情况下,我都可以让该字段显示在我的 API 结果中,但是在尝试对其进行排序时仍然会收到 FieldError。使用自定义过滤器是我唯一的选择吗?
    • 如果您只想按多户提交的顺序订购。另一个解决方案,您可以从 Daniel Roseman stackoverflow.com/questions/4309062/… 覆盖 queryset = Recipe.objects.all()
    • 我不确定这对我有什么帮助,但我也想对其他字段进行排序。
    • 请发布您的整个错误消息,FieldError 之后是什么:无法将关键字 u'ingredients_length' 解析为字段。选择是什么?
    猜你喜欢
    • 1970-01-01
    • 2018-06-23
    • 2021-06-21
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 2015-03-25
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多