django - 如何使用多个重型 ModelChoiceFields 加速模板显示?
问题描述
通过一个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>
更进一步,您可以添加模板片段缓存。
推荐阅读
- android - android中的PendingIntent.FLAG_UPDATE_CURRENT和0有什么不同?
- linux - u-boot中的fatloat地址限制
- ios - 自定义展开 segue 类在 Swift 中无法正常工作,为什么?
- laravel-5 - Laravel:只显示自己的帖子
- python - Cython 示例失败
- postgresql - 从不同的组中选择每 2 个随机记录
- xcode - 我怎么知道 fbAudienceNetwork 是否真的有效?
- java - AIDE 是否支持 Firebase?
- angular - ionic2 本地存储获取
- mysql - Code Igniter 中的 Case-When 条件