如何使用多个繁重的模型选择字段加速模板显示?



通过django形式,我想显示相当多的ModelChoiceFields。这些字段是相同的(显示相同的人员列表(。但是,问题是我有很多这些字段的条目。我拥有的字段越多,加载模板所需的时间就越多,即使我认为查询集(每个字段都相同(只会被计算一次。

>假设和问题我的假设是,查询集的计算次数与必填字段的数量一样多。如果这是正在发生的事情,我不知道如何优化我的字段初始化方式


我想要什么和我不想要什么

  • 我不是在寻找实时搜索解决方案(ajax 有点(,
  • 当只有一个字段时,条目数是可以接受的(我有一个搜索字段来过滤人员(,
  • 当我有越来越多的字段要显示时,即使每个字段的查询集相同,问题也会真正发生。
<小时 />

我的代码

from django import forms
from . import exceptions
from django.contrib.auth.models import Group, User
class MyForm(forms.Form):
# defining a dict here, and using it in __init__ to define multiple fields within a loop
# NOTE : 'pc{i}' will be the name of one of the fields. queryset for each is defined in __init__
nb_pcs = 16
pcs_dict = {}
for i in range(1, nb_pcs + 1):
pcs_dict.update({
f'pc{i}': forms.ModelChoiceField(queryset=None, required=False)
})
def __init__(self, *args, **kwargs):

# getting user through kwargs
self.user = kwargs.pop('user', None)
if not self.user: raise exceptions.DontKnowWhoFillsForm_Error()
super(MyForm, self).__init__(*args, **kwargs)

# defining the queryset that will be used for each field 'pc{i}'
user_queryset = User.objects
.filter(groups__name='RegularAccount')
.order_by('last_name')
# defining the fields themselves
for key, value in self.pcs_dict.items():
self.fields[key] = value 
self.fields[key].queryset = user_queryset

非常感谢您的帮助!

首先使用 django-debug-toolbar 找出是什么让你的页面变慢了——它可能是查询集(你已经解决了(,但它可能是模板渲染。

您可以在视图中呈现后端的ModelChoiceField选项,然后使用render_to_string()将其作为上下文传递给模板。

首先为您的选项创建一个模板。

# user_choice_field_options.html
{% for obj in queryset %}
<option value="{{ obj.id }}">{{ obj.first_name }}</option>
{% endfor %}

然后在您的视图中,您将呈现选项并将其作为额外的上下文传递,以便它可以用作模板变量。

from django.template.loader import render_to_string
from django.views.generic import FormView
class MyView(FormView):
template_name = 'my_template.html'
form_class = MyForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
users = (
User.objects
.filter(groups__name='RegularAccount')
.order_by('last_name')
)
context['user_options'] = render_to_string(
'user_choice_field_options.html',
context={'queryset': users},
request=self.request,
)
return context

然后在my_template.html中,您可以根据需要多次手动渲染小部件。

<select name="field_1" required="" id="id_field_1">
<option value="">---------</option>
{{ user_options|safe }}
</select>

为了更进一步,您可以添加模板片段缓存。

最新更新