当一个model的对象很多的时候,查询或过滤功能显得尤为重要,好在Django给我们提供了功能强大的django-filter。
准备工作
pip install django-filter
在settings.py中
增加'django_filters'到INSTALLED_APPS数组
INSTALLED_APPS = [
'simpleui',
'ckeditor',
'ckeditor_uploader',
'allauth',
'allauth.account',
'allauth.socialaccount',
'django_filters',
...
]
REST_FRAMEWORK设置如下:
REST_FRAMEWORK = {
# 过滤器默认后端
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',),
}
定义filter类
所有filter类都继承自filters.FilterSet
class ProjectFilter(filters.FilterSet):
code = filters.CharFilter(lookup_expr='icontains')
owner = filters.ModelMultipleChoiceFilter(queryset=User.objects.all(),field_name="owner")
creater = filters.ModelMultipleChoiceFilter(queryset=User.objects.all(),field_name="creater")
isp = filters.ModelMultipleChoiceFilter(
queryset=Organization.objects.filter( organizationType = OrganizationType_enum["isp"].value),field_name="program__isp")
class Meta:
model = Project
fields = ['code',]
在class Meta中指定model为Project。
code为charField类型,所以可以定义搜索类型为icontains,即为大小写不敏感(见63.ORM查询条件详解:contains和icontains-CSDN博客)
owner和creater为指向User模型的外键,可以进行多选,所以filter类型为ModelMultipleChoiceFilter,并且要指定queryset和field_name。
最后再看isp,和owner不一样的是field_name,为program__isp(两个下划线)。
这里涉及到3个model,Project,Program,Organization。
其中Project中有program外键指向Program,Program中有isp外键指向Organization,program__isp指的就是Project中program的isp。
View函数中使用
@login_required(login_url='/accounts/login/')
def view_project_list(request,program_id):
try:
userObj = request.user
program_list = Program.objects.all()
projects_with_perm = get_objects_for_user(userObj, 'view_project',klass=Project)
if program_id == "all":
program = "all"
projects = projects_with_perm.all()
else:
program = Program.objects.get(id = program_id)
projects = projects_with_perm.filter(program__id = program_id)
filter = ProjectFilter(request.GET, queryset=projects)
split_data = split_page(filter.qs,request)
return render(request, 'project/project_list.html', {
'filter':filter,
'split_data':split_data,
'program_list':program_list,
'program':program,
'program_id':program_id
})
except Exception as err:
return handle_error(request,err)
在html中显示
定义一个modal模态框显示所有的过滤条件
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" id="ModalForm_filter" >
<div class="modal-dialog modal-lg" role="document">
<form action="" method="get" class="form form-inline">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">过滤条件</h4>
</div>
<div class="modal-body">
<div class="form-group">
<div class="col-sm-12 filter_div">
{{ filter.form.as_p }}
</div>
</div>
</div>
<div class="modal-footer" text-center>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button class="btn btn-primary "> <span class="glyphicon glyphicon-filter"></span> 确定</button>
</div>
</div>
</form>
</div>
</div>
效果如下: