【问题标题】:How to show only a few Many-to-many relations in DRF?如何在 DRF 中只显示几个多对多关系?
【发布时间】:2021-07-07 00:19:14
【问题描述】:

例如,如果我有 2 个模型和一个简单的视图:

class Recipe(model.Model):
    created_at = model.DateField(auto_add_now=True)


class RecipeBook(model.Model):
    recipes = model.ManyToManyField(Recipe)

...

class RecipeBookList(ListAPIView):
    queryset = RecipeBook.objects.all()
    serializer_class = RecipeBookSerializer

...

class RecipeBookSerializer(serializers.ModelSerializer):
    recipe = RecipeSerializer(many=True, read_ony=True)
    
    class Meta:
        model = RecipeBook
        fields = "__all__"

当使用简单的GET 方法显示所有餐厅时,最好的方法是只显示创建的前 5 个菜谱而不是全部?

【问题讨论】:

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


    【解决方案1】:

    查询集方式:

    您可以在查询集中指定自定义Prefetch 操作来限制预取的相关对象:

    queryset.prefetch_related(Prefetch('recipes', queryset=Recipe.objects.all()[:5]))
    

    文档:https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-objects

    序列化方式:

    您可以使用source 提供自定义方法来返回自定义查询集

    class RecipeBookSerializer(serializers.ModelSerializer):
        recipes = RecipeSerializer(many=True, read_only=Treue, source='get_recipes')
    
        class Meta:
            model = RecipeBook
            fields = "__all__"
    
        def get_recipes(self, obj):
            return obj.recipes.all()[:5]
    

    然后使用prefetch_related("recipes") 最小化相关查询。

    来源:django REST framework - limited queryset for nested ModelSerializer?

    序列化方法的问题在于,要么对每个食谱书对象执行一个相关的食谱查询,要么从一开始就预取所有相关的食谱。

    【讨论】:

    • 这种方法存在 N+1 问题,因为您将根据您展示的每本食谱书对食谱进行额外的数据库查询
    • 哦,是的,这是真的,谢谢@Alexandr,ant idea 提供更优化的解决方案?
    • 不错,没注意到这个问题。使用改进的查询进行编辑
    • 在查询时不会prefetch_related 全部拉取吗? (我想避免这种情况)有什么方法可以避免这样做并指定获取最近的 5 个?
    • 好的,我想我找到了一个解决方案来限制 pre_fetched 元素的数量,这个答案stackoverflow.com/a/37086807/7269139 感谢 Dan/Alex 的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2021-11-13
    • 2023-01-27
    • 2014-07-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    相关资源
    最近更新 更多