一、filter
效果图


知识点
1.配置得显示Filter,不配置就不显示了
list_filter = ['title','publish', 'authors']
2.前端显示
后端返回 字典
eg:{"publish":["<a href=''>全部</a>","<a href=''>南京出版社</a>","<a href=''>上海出版社</a>"]
"authors":["<a href=''>全部</a>","<a href=''>yuan</a>","<a href=''>egon</a>"]
}
{% if showlist.config.list_filter %}
<h4>Filter</h4>
{% for filter_field, linktags in showlist.get_filter_linktags.items %}
<div class="well">
<p>{{ filter_field.upper }}</p>
{% for link in linktags %}
<p>{{ link|safe }}</p>
{% endfor %}
</div>
{% endfor %}
{% endif %}
3.get_filter_linktags 返回 字典
知识:
1.根据字段 str 取到模型得字段对象
filter_field_obj = self.config.model._meta.get_field(filter_field)
model_name = self.config.model._meta.model_name # 模型名 book
app_label = self.config.model._meta.app_label # app名 app01
2.一对多,多对多,
就是 ForeignKey ManyToManyField 得对象
app01.Book.publish
<class 'django.db.models.fields.related.ForeignKey'>
app01.Book.authors
<class 'django.db.models.fields.related.ManyToManyField'>
3.根据一对多,多对多得对象 找关联得模型表,数据
print("rel...", filter_field_obj.rel.to.objects.all())
rel... <QuerySet [<Publish: 南京出版社>, <Publish: 上海出版社>, <Publish: 河北出版社>]>
rel... <QuerySet [<Author: yuan>, <Author: egon>, <Author: alex>]>
4.取数据,普通字段,和关联字段分开取
if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField):
data_list = filter_field_obj.rel.to.objects.all() # 关联对象 适用 一对多,多对多
else: # 普通字段
data_list = self.config.model.objects.all().values('pk', filter_field)
5.处理全部标签时
注意:url 上面已经有了该field, 全部,就取消该field, del params[filter_field]
url 上面没有,那就没有
temp = []
if params.get(filter_field):
del params[filter_field]
temp.append("<a href='?%s'>全部</a>" % (params.urlencode()))
else:
temp.append("<a href='#' class='active'>全部</a>")
6.处理数据标签
注意:分开处理关联字段和普通字段
params = copy.deepcopy(self.request.GET)
为url加一个params
params[filter_field] = pk
params[filter_field] = text
每一次取数据都要保留 正在访问得 url 并加上正在访问得field!
_url = params.urlencode()
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
正在点击得,得加上样式 active
if cid == str(pk) or cid == text:
link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text)
else:
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
# 处理数据标签
for obj in data_list:
if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
pk = obj.pk
text = str(obj)
params[filter_field] = pk
else:
pk = obj.get('pk')
text = obj.get(filter_field)
params[filter_field] = text
_url = params.urlencode() # 序列化后得结构
if cid == str(pk) or cid == text:
link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text)
else:
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
temp.append(link_tag)
link_dic[filter_field] = temp
def get_filter_linktags(self):
print('list_filter:',self.config.list_filter) # ['title', 'publish', 'authors']
link_dic = {}
import copy
for filter_field in self.config.list_filter:
params = copy.deepcopy(self.request.GET)
cid = self.request.GET.get(filter_field, 0)
filter_field_obj = self.config.model._meta.get_field(filter_field)
print(filter_field_obj)
print(type(filter_field_obj))
"""
app01.Book.title
<class 'django.db.models.fields.CharField'>
app01.Book.publish
<class 'django.db.models.fields.related.ForeignKey'>
app01.Book.authors
<class 'django.db.models.fields.related.ManyToManyField'>
"""
from django.db.models.fields.related import ForeignKey
from django.db.models.fields.related import ManyToManyField
# print("rel...", filter_field_obj.rel.to.objects.all())
# rel... <QuerySet [<Publish: 南京出版社>, <Publish: 上海出版社>, <Publish: 河北出版社>]>
# rel... <QuerySet [<Author: yuan>, <Author: egon>, <Author: alex>]>
if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField):
data_list = filter_field_obj.rel.to.objects.all() # 关联对象 适用 一对多,多对多
else: # 普通字段
data_list = self.config.model.objects.all().values('pk', filter_field)
# 处理全部标签
temp = []
if params.get(filter_field):
del params[filter_field]
temp.append("<a href='?%s'>全部</a>" % (params.urlencode()))
else:
temp.append("<a href='#' class='active'>全部</a>")
# 处理数据标签
for obj in data_list:
if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
pk = obj.pk
text = str(obj)
params[filter_field] = pk
else:
pk = obj.get('pk')
text = obj.get(filter_field)
params[filter_field] = text
_url = params.urlencode() # 序列化后得结构
if cid == str(pk) or cid == text:
link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text)
else:
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
temp.append(link_tag)
link_dic[filter_field] = temp
return link_dic
4.Q查询 and
def list_view(self, request):
...
...
# 获取filter得Q对象
filter_condition = self.get_filter_condition(request)
# 筛选当前表得所有数据
data_list = self.model.objects.all().filter(search_connection).filter(filter_condition)
...
...
# Q对象
def get_filter_condition(self, request):
filter_condition = Q() # 默认是 and 不是 or, 根据str,查找val
for filter_field, val in request.GET.items():
if filter_field in self.list_filter:
filter_condition.children.append((filter_field, val))
return filter_condition
补充:
Q查询根据字段
bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
Q查询根据str
filter_condition = Q()
filter_consition.connector = "or" # 如果不写默认是 and
filter_condition.children.append(("title","yuan"))
filter_condition.children.append(("date","2018-12-12"))
Book.object.filter(filter_condition)
app01/stark.py
![]()
# -*- coding:utf-8 -*-
from stark.service import stark
from .models import *
from django.forms import ModelForm
class BookModelForm(ModelForm):
class Meta:
model = Book
fields = "__all__"
labels = {
"title": '书籍名称',
"price": '价格',
'publishDate': '出版日期'
}
from django.shortcuts import HttpResponse
class BookConfig(stark.ModelStark):
list_display = ['title', 'price','publishDate']
list_display_links = ['title']
modelform_class = BookModelForm
search_fields = ['title', 'price']
def patch_init(self, request, queryset):
# print("queryset",queryset)
queryset.update(price=123)
return HttpResponse('批量初始化OK')
patch_init.short_description = "批量初始化"
actions = [patch_init]
list_filter = ['title','publish', 'authors']
stark.site.register(Book, BookConfig)
stark.site.register(Publish)
stark.site.register(Author)
stark.site.register(AuthorDetail)
stark.py