我正在编写一个端点来从Django REST框架中的“Term”模型中获取数据,我试图通过预取数据来减少查询。具体来说,有一个模型“TermRelation”,它保存了我想从中预取数据的各个术语之间的向量关系得分。简化后的模型如下所示:
models.py
class Term(models.Model):
term = models.CharField(max_length=255, verbose_name=_('Term'), null=True, db_index=True)
class TermRelation(models.Model):
src_term = models.ForeignKey(Term, on_delete=models.CASCADE, verbose_name=_('Source term'),
related_name='src_term_relation')
trg_term = models.ForeignKey(Term, on_delete=models.CASCADE, verbose_name=_('Target term'),
related_name='trg_term_relation')
vector_sim = models.FloatField(blank=True, null=True, default=0.0, verbose_name=_('Vector similarity'), help_text=_('Cosine vector similarity.'))
下面是简化的视图:
views.py
class TermsList(generics.ListCreateAPIView):
def get_queryset(self):
queryset = Term.objects.prefetch_related(
'src_term_relation',
'trg_term_relation',
'note_set',
'usage_set'
).all()
return queryset
还有其他与术语相关的模型,例如“Note”和“Usage”,预取正在工作,只有对于关系,它仍然进行一系列查询。我已经包含了Django SQL debug结果的屏幕截图,或者更确切地说,前面的几行,因为这将持续一段时间,使用相同的查询。你可以看到Django确实运行了预取操作,但仍然会进行相同的查询,就好像它没有发生一样。
我做错了什么?这是否与“TermRelation”有两个指向同一模型的ForeignKey字段或REST框架不知道如何解析相关名称有关?
编辑:
我想我找到了一些东西,问题似乎在别处。在序列化器中,有一个方法字段用于计算关系的数量:
class TermSerializer(serializers.ModelSerializer):
relations_count = serializers.SerializerMethodField()
def get_relations_count(self, obj):
rels = TermRelation.objects.filter(Q(src_term=obj) | Q(trg_term=obj))
return len(rels)
class Meta:
model = Term
fields = '__all__'
我假设它对序列化器返回的每个术语的所有TermRelations运行一个查询,忽略预取的数据。有没有更好的办法?
1条答案
按热度按时间mgdq6dx11#
试试这个,也许它会解决额外的查询问题