【发布时间】:2017-11-27 14:55:27
【问题描述】:
我的一个列表页面有一个提供unicode功能的相关模型。 我尝试预取以防止重复查询。
预取查询如下:
SELECT "pansys_modulex"."id", "pansys_modulex"."client", "pansys_modulex"."change_date", "pansys_modulex"."changed_by_id", "pansys_modulex"."create_date", "pansys_modulex"."created_by_id", "pansys_modulex"."language_id", "pansys_modulex"."short_text", "pansys_modulex"."module_id" FROM "pansys_modulex" WHERE ("pansys_modulex"."language_id" = '3' AND "pansys_modulex"."module_id" IN ('8', '9', '10', '12', '13', '14'))
不过,我还是收到了几十个重复的查询,如下所示:
SELECT "pansys_modulex"."id", "pansys_modulex"."client", "pansys_modulex"."change_date", "pansys_modulex"."changed_by_id", "pansys_modulex"."create_date", "pansys_modulex"."created_by_id", "pansys_modulex"."language_id", "pansys_modulex"."short_text", "pansys_modulex"."module_id" FROM "pansys_modulex" WHERE ("pansys_modulex"."language_id" = '3' AND "pansys_modulex"."module_id" = '8')
我在这里缺少什么? 我想我会预取查询,如果可以的话,django 会尝试使用预取结果。
编辑: 我的模型和预取命令本身。
#models trimmed
class Application(GenericCommonModel):
module = models.ForeignKey(Module, verbose_name=_('Module'))
class Module(GenericCommonModel):
def __unicode__(self):
short_text = None
try:
language = PanBasLanguage.objects.get(language=get_language())
short_text = ModuleX.objects.get(module = self,language = language).short_text
except ModuleX.DoesNotExist:
print 'ModuleX > DoesNotExist'
return short_text or self.abbreviation
class ModuleX(models.Model):
module = custom_model_fields.PanNotNullForeignKey(Module, on_delete=models.CASCADE)
language = custom_model_fields.PanNotNullForeignKey('panbas.PanBasLanguage')
short_text = custom_model_fields.PanShortTextField()
class Meta:
verbose_name = _('Module Description')
verbose_name_plural = _('Module Descriptions')
unique_together = ('module', 'language')
class PanBasLanguage(GenericBasicModel):
language_choices = settings.LANGUAGES
language = custom_model_fields.PanNoneBlankCharField(choices=language_choices, max_length=8,
verbose_name=_('Language'), unique=True)
#in my view
language = PanBasLanguage.objects.get(language=get_language())
x_result = ModuleX.objects.filter(language=language)
prefetch = Prefetch('module__modulex_set', queryset=x_result)
queryset = queryset.prefetch_related(prefetch)
简而言之,Language 模型有可用的语言,Module 有 ModuleX 模型来保存不同语言的短文本。在我的应用程序列表中,我在列中打印出模块,并且该模块单独进行 modulex 查找。
【问题讨论】:
-
请添加您构建的实际 Django 查询集和模型。随意修剪模型以仅显示关系字段,以便我们查看关系。
-
编辑了我的问题。
-
里面有些东西是不透明的,比如“Prefetch”类。但最突出的是 unicode 方法。如果您只是返回单个模型字段或将其全部删除会发生什么?
-
我返回了一个字段,所有的 modulex 重复项都消失了。如果我删除预取类并简单地做 queryset.prefetch_related('module__modulex_set') ,结果是一样的。我使用 Prefetch 类首先使用活动语言过滤 modulex 结果。