Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Django ORM预取间接相关项_Django_Query Optimization_Django Orm - Fatal编程技术网

使用Django ORM预取间接相关项

使用Django ORM预取间接相关项,django,query-optimization,django-orm,Django,Query Optimization,Django Orm,我正在尝试优化我的调节系统的查询,使用Django和DRF构建。 我目前一直在重复检索:目前,我有 类AdminSerializer(ModelSerializer): 重复项=SerializerMethodField() def获取副本(自身、项目): 如果允许,则: qs=[] 其他: qs=Item.objects.filter( 允许=真, related\u stuff\u language=item.related\u stuff.language ).注释( 相似性=Trigra

我正在尝试优化我的调节系统的查询,使用Django和DRF构建。 我目前一直在重复检索:目前,我有

类AdminSerializer(ModelSerializer):
重复项=SerializerMethodField()
def获取副本(自身、项目):
如果允许,则:
qs=[]
其他:
qs=Item.objects.filter(
允许=真,
related\u stuff\u language=item.related\u stuff.language
).注释(
相似性=TrigramSimilarity('name',item.name)
).filter(相似性\uu gt=0.2).按('-similarity')[:10]排序
返回AdminMinimalSerializer(qs,many=True)
它工作正常,但对要显示的每个项目至少执行一个附加查询。此外,如果存在重复项,我将执行其他查询以填充
AdminMinimalSerializer
,其中包含重复项的字段和相关对象。我可能可以通过在序列化程序中使用与预取相关的来减少开销,但这并不妨碍我对每个项进行多次查询(假设我在
AdminMinimalSerializer
中只有一个相关项要预取,我仍然有~2N+1个查询:1个用于项,N个用于重复项,N个用于重复项的相关项)

我已经查看了
子查询
,但是我无法检索对象,只能检索id,这在我的例子中是不够的。我尝试在
预回迁
对象和
注释中使用它

我还尝试了类似
Item.filter(allowed=False).prefetch(prefetch(“related\u stuff\u language\u related\u stuff\u set\u items”,queryset=items.filter…,to\u attr=“duplicates”)
,但是
duplicates
属性被添加到了“related\u stuff\u language\u related\u stuff\u stuff\u\u-stuff\u集”,所以我无法真正使用它

我欢迎任何意见;)

编辑:真正的代码存在。玩具示例如下:

#models.py
从django.db.models导入Model、CharField、ForeignKey、CASCADE、BooleanField
教材(模型):
title=CharField(最大长度=250)
serie=外键(serie,on\u delete=CASCADE,related\u name=“books”)
允许=布尔字段(默认值=False)
等级系列(型号):
title=CharField(最大长度=250)
language=ForeignKey(语言,on_delete=CASCADE,related_name=“series”)
课堂语言(模型):
name=CharField(最大长度=100)
#serializers.py
从django.contrib.postgres.search导入相似性
从rest_framework.serializers导入ModelSerializer,SerializerMethodField
从。模型导入书籍、语言、系列
类BookAdminSerializer(ModelSerializer):
类元:
模型=书
字段=(“id”、“标题”、“系列”、“重复项”)
serie=SeriedMinauxSerializer()
重复项=SerializerMethodField()
def获取副本(自我、书本):
“”“检索书本的副本”“”
如果允许:
qs=[]
其他:
qs=(
Book.objects.filter(
允许=真,serie\u语言=book.serie.language)
.注释(相似性=三元相似性(“书名”,书名))
.过滤器(相似性\uu gt=0.2)
.order_by(“-相似性”)[:10]
)
返回BookAdminMinimalSerializer(qs,many=True)
类BookAdminSerializer(ModelSerializer):
类元:
模型=书
字段=(“id”、“标题”、“系列”)
serie=SeriedMinauxSerializer()
类SeriedMinauxSerializer(ModelSerializer):
类元:
型号=系列
字段=(“id”、“语言”、“标题”)
language=LanguageSerializer()
类语言序列化程序(ModelSerializer):
类元:
模型=语言
字段=('id','name')
我正试图找到一种预取相关对象和副本的方法,这样我就可以摆脱
BookSerializer
中的
get_duplicates
方法,它会导致N+1个查询,并且在我的
BookSerializer
中只有一个
duplicates
字段

关于数据,以下是预期输出:

[
    {
        "id": 2,
        "title": "test2",
        "serie": {
            "id": 2,
            "language": {
                "id": 1,
                "name": "English"
            },
            "title": "series title"
        },
        "duplicates": [
            {
                "id": 1,
                "title": "test",
                "serie": {
                    "id": 1,
                    "language": {
                        "id": 1,
                        "name": "English"
                    },
                    "title": "first series title"
                }
            }
        ]
    },
    {
        "id": 3,
        "title": "random",
        "serie": {
            "id": 3,
            "language": {
                "id": 1,
                "name": "English"
            },
            "title": "random series title"
        },
        "duplicates": []
    }
]