我需要有多语种网站。为此,我写了django模块,它收集了大量关于国家,城市及其翻译的信息,几乎所有语言。
以下是该模块的简短版本:
class LanguagesGroups(models.Model):
class Meta:
verbose_name = 'Language Group'
class Languages(models.Model):
iso_code = models.CharField("ISO Code", max_length=14, db_index=True)
group = models.ForeignKey(LanguagesGroups, on_delete=models.CASCADE, verbose_name='Group of ISO',
related_name='group', db_index=True)
class Cities(models.Model):
population = models.IntegerField(null=True)
territory_km2 = models.IntegerField(null=True)
class CitiesTranslations(models.Model):
common_name = models.CharField(max_length=188, db_index=True)
city = models.ForeignKey(Cities, on_delete=models.CASCADE, verbose_name='Details of City')
lang_group = models.ForeignKey(LanguagesGroups, on_delete=models.CASCADE, verbose_name='Language of city',
null=True)
class Meta:
index_together = (['common_name', 'city'],
['city', 'lang_group'])
我想向用户展示一些有关用户使用翻译版本的城市请求的地点的数据(取决于用户设置):
class Profile(models.Model):
title = models.CharField(_('title'), max_length=120)
info = models.TextField(_('information'), max_length=1500, blank=True)
city = models.ForeignKey(Cities, verbose_name=_('city'), null=True, blank=True)
def get_city(self):
user_lang = get_language() # en
lang_group = Languages.objects.get(iso_code=user_lang).group # 1823
return CitiesTranslations.objects.get(city=self.city, lang_group=lang_group).common_name
template.html
{% for item in object_list %}
{{ item.title }}
{{ item.get_city }}
{{ item.info }}
{% endfor %}
当我添加{{ item.get_city }}
时,如果是分页,每页只有25个项目,页面加载速度最多下降18次,查询量(根据django-debug-tool)从2上升django-debug-tool告诉我大约25个重复。
如何解决这种缓慢问题?
修改 我的观点
class ProfileListView(ListView):
model = Profile
template_name = 'profiles/profiles_list.html'
context_object_name = 'places_list'
paginate_by = 25
答案 0 :(得分:1)
首先,如果你想要速度 - 你应该尝试caching。
您还可以优化查询。
def get_city(self):
user_lang = get_language() # en
return CitiesTranslations.objects.get(
city=self.city_id, lang_group__group__iso_code=user_lang
).common_name
您可能还想要的是批量获取所有内容,而不是使用单独的方法调用。假设我们有object_list
:
city_ids = [x.city_id for x in object_list]
city_translations = CitiesTranslations.objects.filter(
city__in=city_ids, lang_group__group__iso_code=user_lang
).values_list('city_id', 'common_name')
city_translations = dict(city_translations)
for obj in object_list:
obj.city_name = city_translations[obj.city_id]
您可以将此代码放在视图中的某个位置。您还必须在模板中将{{ item.get_city }}
更改为{{ item.city_name }}
。