django-autocomplete-light性能优化
1.介绍
admin和xadmin的编辑页中,外键或者多对多的字段会显示为一个select标签,并将关联的数据一股脑的加载到页面上,这在关联大量数据时会极大的影响效率
django-autocomplete-light 是一个轻量级的自动补全插件,类似搜索引擎自动给出的搜索建议,页面中select标签中的数据不会随着页面的加载而加载,而是等到输入时再根据输入的内容进行搜索,类似于懒加载
该插件的原理:封装好一个查询接口,并提供一个前端组件(自定义form时可以使用),当用户输入数据时调用接口实时查询,供用户选择
2.引入插件
pip install django-autocomplete-light==3.2.10
INSTALLED_APPS = [
# ...
'dal', # 自动补全插件
'dal_select2',
]
3.配置后端查询逻辑,项目主目录下新建 autocomplete.py
from dal import autocomplete
from blog.models import Category, Tag
# 配置所有需要自动补全的接口,可以理解为自动补全的view层
class CategoryAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
# 若未登录,则返回空的queryset,因结果还会被其他模块处理,所以不能直接返回None
if not self.request.user.is_authenticated():
return Category.objects.none()
qs = Category.objects.filter(owner=self.request.user)
# 这里的q是url上传递过来的查询参数
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
4.配置查询接口 urls.py
from .autocomplete import TagAutocomplete, CategoryAutocomplete
urlpatterns = [
# ......
url(r'^category-autocomplele/$', CategoryAutocomplete.as_view(), name='category-autocomplete'),
url(r'^tag-autocomplele/$', TagAutocomplete.as_view(), name='tag-autocomplete'),
]
此时已经可以通过url访问接口了
查询所有以dj开头的分类
http://127.0.0.1:8000/category-autocomplele/?q=dj
5.配置展示逻辑
django-autocomplete-light已提供Form层的组件来帮助我们更好的接入后端接口 adminforms.py
from django import forms
from dal import autocomplete
from .models import Tag, Category, Post
# 自定义编辑页面中表单元素的样式,调用自动补全接口
class PostAdminForm(forms.ModelForm):
desc = forms.CharField(widget=forms.Textarea, label='摘要', required=False)
# 使用自动补全的接口组件
category = forms.ModelChoiceField(
queryset=Category.objects.all(),
# 参数url对应的是url中的name
widget=autocomplete.ModelSelect2(url='category-autocomplete'),
label='分类',
)
# tag为多对对字段,组件名跟category有差异
tag = forms.ModelMultipleChoiceField(
queryset=Tag.objects.all(),
# 这边也不一样
widget=autocomplete.ModelSelect2Multiple(url='tag-autocomplete'),
label='标签',
)
# 可以不配置Meta,此处是为避免出现js资源冲突问题
class Meta:
model = Post
# 需要自动补全的字段要放到前面
fields = ('category', 'tag', 'title', 'desc', 'content', 'status')
参考:《Django企业开发实战》