django-autocomplete-light 使用(二)
背景摘要
当我们在使用 dajngo admin 或者 xadmin 中 foreignKey 字段时, 后台默认提供是 select2 复选框, 加入我们该字段对应的数据量很多时, 会出现加载很慢的情况,出现这种情况是由于后台默认会给我们加载出该字段所有 model 提供我们去选择, 但实际情况我们只需要其中的某个 model 与当前 model对应即可, 减少不必要的开销。查找相关资料发现django-autocomplete-light能解决该问题。
django-autocomplete-light 使用
安装
pip install django-autocomplete-light
pip install django-querysetsequence
项目 setting 文件中配置相关 django-autocomplete-light app
INSTALLED_APPS = [
‘dal’, # 新增(注意顺序, 最好放在首位)
‘dal_select2’, # 新增
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘xadmin’,
‘crispy_forms’,
‘reversion’,
]
models.py
class User(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=32)
avatar = models.CharField(max_length=255)
expiredAt = models.BigIntegerField()
def expired_time(self):
if self.expiredAt:
local_time = time.localtime(self.expiredAt / 1000.0)
format_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
else:
format_time = ''
return format_time
class Meta:
db_table = 'user'
def __str__(self):
return 'userId: %s-username: %s' %(self.id, self.name)
class Project(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=32)
createdAt = models.BigIntegerField()
def created_time(self):
if self.createdAt:
local_time = time.localtime(self.createdAt / 1000.0)
format_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
else:
format_time = ''
return format_time
class Meta:
db_table = 'project'
def __str__(self):
return 'projectId: %s-projectName: %s' %(self.id, self.name)
lass UserProjectRelationship(models.Model):
userId = models.ForeignKey(User, on_delete=None, db_column='userId')
projectId = models.ForeignKey(Project, on_delete=None, db_column='projectId')
enable = models.BooleanField(default=True)
createdAt = models.BigIntegerField()
def created_time(self):
if self.createdAt:
local_time = time.localtime(self.createdAt / 1000.0)
format_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
else:
format_time = ''
return format_time
def save(self, *args, **kwargs):
current_time = time.time() * 1000
if not self.createdAt:
self.createdAt = current_time
super(UserProjectRelationship, self).save(*args, **kwargs)
class Meta:
db_table = 'user_project_relationship'
app 中配置路由
from django.conf.urls import url
from project import views
urlpatterns = [
url(r'^user-autocomplete/$', views.UserAutoComplete.as_view(), name='user-autocomplete'),
url(r'^project-autocomplete/$', views.ProjectAutoComplete.as_view(), name='project-autocomplete'),
]
app 中增加视图函数
from django.shortcuts import render
from dal import autocomplete
from django.db.models import Q
from . models import User, Project
# Create your views here.
class UserAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated: # 这里校验是否为登录用户
return User.objects.none()
if self.q:
qs = User.objects.all()
qs = qs.filter(Q(id__icontains=self.q) | Q(name__icontains=self.q)) # 复选框搜索条件(id 和 名称)
else:
qs = User.objects.none()
return qs
class ProjectAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Project.objects.none()
if self.q:
qs = Project.objects.all()
qs = qs.filter(Q(id__icontains=self.q) | Q(name__icontains=self.q))
else:
qs = Project.objects.none()
return qs`
app 中添加 forms.py 文件
from django import forms
from dal import autocomplete
from .models import ProjectServiceResultTypeRelationship, UserProjectRelationship
class UserProjectRelationshipForm(forms.ModelForm):
class Meta:
model = UserProjectRelationship
fields = ('__all__')
widgets = {
'userId': autocomplete.ModelSelect2(url='user-autocomplete'),
'projectId': autocomplete.ModelSelect2(url='project-autocomplete')
}
```
### adminx.py 文件中使用对应的 forms models
```
import xadmin
from xadmin import views
from .models import UserProjectRelationship
from .forms import UserProjectRelationshipForm
@xadmin.sites.register(UserProjectRelationship)
class UserProjectRelationshipModelAdmin(object):
form = UserProjectRelationshipForm # 使用 forms.py 中定义的 UserProjectRelationshipForm
list_display = ['id', 'userId', 'projectId', 'created_time']
list_filter = ['id', 'userId', 'projectId']
exclude = ['createdAt']
进入后台:
- 加入
auto-complete-light后台展示


- 未加入
auto-complete-light后台展示:

注意⚠️:使用 django 版本在 2.2 以下,否则可能会出现 django-auto-complete-light 不生效
django-auto-complete-light demo
本文介绍如何使用django-autocomplete-light库优化大型数据集的多选字段选择,减少后台负载,提高用户体验。内容包括安装、项目设置、模型配置、路由与视图函数的添加以及forms.py的修改,通过示例展示了使用该库前后的后台界面差异。
408

被折叠的 条评论
为什么被折叠?



