问题摘要
我有一个基于类的列表视图,它只显示每个对象的链接以及来自一些对象字段的一些数据.链接的href
是使用我在模型本身中编写的get_absolute_url
方法生成的.问题是每次运行Get_Abte_url时都会查询数据库.这会导致许多重复查询(将来对象更多时,这将是一个问题).
try 的解决方案
我的Get_Abte_url方法从我的模型访问一些ForeignKey字段,所以我try 在我的视图中为我的查询集使用.Select_Related().然而,这并没有改变任何事情.
问题
如何通过运行Get_Abte_url来消除重复的查询?
Code
Models.py
class LanguageLocale(models.Model):
"""model for representing language locale combinations"""
class LANG_CODES(models.TextChoices):
EN = 'en', _('English')
ES = 'es', _('español')
QC = 'qc', _("K'iche'")
lang = models.CharField(max_length=2, choices=LANG_CODES.choices, blank=False)
class Scenario(models.Model):
"""model for representing interpreting practice scenarios"""
scenario_id = models.CharField(max_length=20, primary_key=True)
lang_power = models.ForeignKey(LanguageLocale)
lang_primary_non_power = models.ForeignKey(LanguageLocale)
class SCENARIO_STATUSES(models.TextChoices):
PROD = 'PROD', _('Production')
STGE = 'STGE', _('Staged')
EXPR = 'EXPR', _('Experimental')
status = models.CharField(
max_length=4, choices=SCENARIO_STATUSES.choices, default='EXPR')
def get_absolute_url(self):
"""Returns the URL to access a detail record for this scenario."""
return reverse('dialogue-detail', kwargs={
'lang_power': self.lang_power.lang,
'lang_primary_non_power': self.lang_primary_non_power.lang,
'pk': self.scenario_id
}
)
Views.py
class ScenarioListView(generic.ListView):
"""View class for list of Scenarios"""
queryset = Scenario.objects.select_related(
'domain_subdomain', 'lang_power', 'lang_primary_non_power'
)
demo = Scenario.objects.get(scenario_id='demo')
prod = Scenario.objects.filter(status='PROD')
staged = Scenario.objects.filter(status='STGE')
experimental = Scenario.objects.filter(status='EXPR')
extra_context = {
'demo': demo,
'prod': prod,
'staged': staged,
'experimental': experimental,
}
Scenario_list.html
{% extends "home.html" %}
{% block content %}
<h1>Practice Dialogues</h1>
<section>
{% if prod %}
<ul>
{% for scenario in prod %}
<li>
<a href="{{ scenario.get_absolute_url }}">{{ scenario.title }}</a> ({{
scenario.domain_subdomain.domain }})
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no practice scenarios. Something went wrong.</p>
{% endif %}
</section>
{% if user.is_staff %}
<section>
{% if staged %}
<article>
<h2>Staged Dialogues</h2>
<ul>
{% for scenario in staged %}
<li>
<a href="{{ scenario.get_absolute_url }}">{{ scenario.title }}</a> ({{
scenario.domain_subdomain.domain }})
</li>
{% endfor %}
</ul>
</article>
{% endif %}
{% if experimental %}
<article>
<h2>Experimental Dialogues</h2>
<ul>
{% for scenario in experimental %}
<li>
<a href="{{ scenario.get_absolute_url }}">{{ scenario.title }}</a> ({{
scenario.domain_subdomain.domain }})
</li>
{% endfor %}
</ul>
</article>
{% endif %}
</section>
{% endif %}
{% endblock %}
重复查询读数(从Django调试工具栏)
此查询重复3次:
SELECT "scenario_languagelocale"."id",
"scenario_languagelocale"."lang_locale",
"scenario_languagelocale"."lang"
FROM "scenario_languagelocale"
WHERE "scenario_languagelocale"."id" = 1
LIMIT 21 6 similar queries. Duplicated 3 times.
此查询重复两次:
SELECT "scenario_languagelocale"."id",
"scenario_languagelocale"."lang_locale",
"scenario_languagelocale"."lang"
FROM "scenario_languagelocale"
WHERE "scenario_languagelocale"."id" = 3
LIMIT 21 6 similar queries. Duplicated 2 times.