Django form queryset=model.objects.all() 加载缓慢
Posted
技术标签:
【中文标题】Django form queryset=model.objects.all() 加载缓慢【英文标题】:Django form queryset=model.objects.all() loads slowly 【发布时间】:2017-01-12 16:34:46 【问题描述】:我有一个简单的模型:
class Sheker(models.Model):
name = models.CharField(max_length=90)
display_name = models.CharField(max_length=90, null=True)
search_name = models.CharField(max_length=90, null=True)
def __unicode__(self):
return self.search_name
class Sod(models.Model):
name = models.CharField(null=False, blank=False, max_length=100)
sheker = models.ManyToManyField(Sheker, blank=True, name='sheker')
用一个简单的形式:
from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rosh.models import *
class SodForm(forms.ModelForm):
sheker = forms.ModelMultipleChoiceField(
queryset=Sheker.objects.all(),
widget=FilteredSelectMultiple("sheker", is_stacked=False),
required=False
)
模型Sheker
在数据库中有超过 12K 行(带有地理扩展的 postgres)-问题是它使表单加载超慢 = 加载 html 超过 5 秒。
问题是queryset=Sheker.objects.all()
吗?我怎样才能让它加载得更快/缓存它或其他东西来快速加载页面(作为普通网页)。
解决此类问题的最佳做法是什么?
【问题讨论】:
虽然查询 12K 对象可能需要一段时间(“超级慢”到底是什么意思?)我猜,主要问题是在 html 模板上渲染 12K 行。你有没有考虑过用户体验?用户如何从 12K 选项列表中进行选择?您的方法还有其他替代方案吗? 哦,你有看过代码吗?来自 django 管理员的小部件 FilteredSelectMultiple 负责处理它。我会添加一些截图。 即使您使用 FliteredSelectMultiple 小部件,向用户提供 12K 选项供您选择也不是很友好。如果您可以以某种方式过滤列表(可能在获取列表之前询问用户一些问题),您可以使其更加用户友好并加快页面速度。 【参考方案1】:如果查询执行的频率更高,您可以使用缓存数据库来保存值,那么这将是一个很好的解决方案。
如果页面经常使用,您可以缓存 [整个视图] (https://docs.djangoproject.com/en/dev/topics/cache/#the-per-view-cache),或者只是查询似乎适合您的应用程序。
您可以像这样缓存查询集结果:
from django.core.cache import cache
from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rosh.models import *
class SodForm(forms.ModelForm):
# Check if the result is already cached
sheker_results = cache.get('sheker_results'): # Returns None if not cached earlier
# If the result is None, then query the database and set the cache
if sheker_results is None:
sheker_results = Sheker.objects.all()
cahce.set('sheker_results', sheker_results)
sheker = forms.ModelMultipleChoiceField(
queryset= sheker_results,
widget=FilteredSelectMultiple("sheker", is_stacked=False),
required=False
)
post 描述了 django 中的缓存。
【讨论】:
【参考方案2】:可能你可以在表单中设置字段自动补全,这样会减轻表单的负担,页面加载很快,字段只会从数据库中加载数据。
然后加速postgresql
【讨论】:
以上是关于Django form queryset=model.objects.all() 加载缓慢的主要内容,如果未能解决你的问题,请参考以下文章
修改django管理字段以使用特定的queryset和表单小部件
Django:将带有相关对象的 QuerySet 转换为 JSON