11 stark组件之delete按钮、filter过滤
1、构建批量删除按钮
1、admin中每个页面默认都有
2、stark之构建批量删除
3、coding
{% extends 'base.html' %} {% block title %} <title>list页面</title> {% endblock %} {% block header %} <h3>list页面</h3> {% endblock %} {% block content %} <a class="btn btn-primary" href="{{ add_url }}">添加数据</a> {% if show_list.config.search_fields %} <form action="" method="get"> <input type="text" class="form-control" style="width: 30%;display: inline-block;margin-top: 8px" name="q" value="{{ show_list.config.key_word }}"> <button class="btn btn-success">submit</button> </form> {% endif %} <form action="" method="post"> {% csrf_token %} <select name="action" class="form-control" style="display: inline-block;width: 200px;margin: 8px 8px 8px 0;height: 35px;vertical-align: -2px"> <option value="">-------</option> {% for item in show_list.get_action_list %} <option value="{{ item.name }}">{{ item.desc }}</option> {% endfor %} </select> <button type="submit" class="btn btn-primary">Go</button> <table class="table table-bordered table-striped"> <tr> {% for header in show_list.get_header %} {# {% for header in header_list %}#} <th>{{ header }}</th> {% endfor %} </tr> {% for data in show_list.get_body %} {# {% for data in new_data_list %}#} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </table> </form> <nav> <ul class="pagination"> {{ show_list.pagination.page_html|safe }} </ul> </nav> {% endblock %} {% block javascript %} <script type="text/javascript"> $('#choice').click(function () { if ($(this).prop('checked')) { //对象自身属性中是否具有指定的属性 $('.choice_item').prop("checked", true) } else { $('.choice_item').prop("checked", false) } }) </script> {% endblock %}
from django.shortcuts import HttpResponse from stark.service import stark from .models import * from django.forms import ModelForm class AuthorConfig(stark.ModelStark): list_display = ['nid', 'name', 'age'] list_display_links = ['name','age'] class BookModelForm(ModelForm): class Meta: model = Book fields = "__all__" labels = { "authors":"作者", "publishDate":"出版日期", } class BookConfig(stark.ModelStark): list_display = ['nid', 'title', 'price'] modelform_class = BookModelForm search_fields = ['title','price'] # 批量修改数据 def patch_init(self,request,queryset): queryset.update(price=111) # return HttpResponse("批量初始化OK") patch_init.short_description = "批量初始化" actions = [patch_init] stark.site.register(Book,BookConfig) stark.site.register(Publish) stark.site.register(Author,AuthorConfig) stark.site.register(AuthorDetail) print(stark.site._registry) """ {<class 'app01.models.Book'>: <stark.service.stark.ModelStark object at 0x0000003AA7439630>, <class 'app01.models.Publish'>: <stark.service.stark.ModelStark object at 0x0000003AA7439668>, <class 'app01.models.Author'>: <stark.service.stark.ModelStark object at 0x0000003AA74396A0>, <class 'app01.models.AuthorDetail'>: <stark.service.stark.ModelStark object at 0x0000003AA7439940>} """
# -*- coding: utf-8 -*- # @Time : 2018/08/17 0017 14:46 # @Author : Venicid from django.conf.urls import url from django.shortcuts import HttpResponse,render,redirect from django.utils.safestring import mark_safe from django.urls import reverse from stark.utils.page import Pagination class ShowList(object): def __init__(self,config, data_list,request): self.config = config # MOdelStark实例对象 self.data_list = data_list # 数据 self.request =request # 分页 data_count = self.data_list.count() current_page = int(self.request.GET.get('page',1)) base_path = self.request.path self.pagination = Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=10, pager_count=11,) # 分页后的数据 self.page_data = self.data_list[self.pagination.start:self.pagination.end] # actions 批量初始化,字段 # self.actions = self.config.actions # [patch_init] self.actions = self.config.new_actions() # [pathch_delete,patch_init,] # 构建数据[{'name':'path_init',"desc":'xxxxx'}] def get_action_list(self): """action批量初始化,构架数据""" temp = [] for action in self.actions: temp.append( {'name':action.__name__, # class的类名 "desc":action.short_description # class的属性 } ) return temp def get_header(self): # 构建表头 header_list = [] # # header_list = ['选择','pk',...'操作','操作'] for field in self.config.new_list_play(): if callable(field): # header_list.append(field.__name__) val = field(self.config, header=True) header_list.append(val) else: if field == "__str__": header_list.append(self.config.model._meta.model_name.upper()) else: val = self.config.model._meta.get_field(field).verbose_name # 中文名称 header_list.append(val) return header_list def get_body(self): # 构建表单 new_data_list = [] for obj in self.page_data: #分页后的数据 # Book表模型,Author表模型 temp = [] for field in self.config.new_list_play(): # ['name','age'] if callable(field): # edit() 可调用的 print(obj,99999999999999999) val = field(self.config,obj) # 直接调用edit()函数 print('val--------->',val) else: val = getattr(obj,field) # 反射 obj是实例对象,name是方法 # list_display_links 按钮 if field in self.config.list_display_links: model_name = self.config.model._meta.model_name app_label = self.config.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) # print(_url) val = mark_safe("<a href='%s'>%s</a>"%(_url,field)) temp.append(val) new_data_list.append(temp) print('new_data_list',new_data_list) # 构造数据 [['jack', 44], ['mark', 33]] return new_data_list class ModelStark(object): list_display = ["__str__"] # 子类中没有,直接用父类自己的 list_display_links = [] modelform_class = [] search_fields = [] # 模糊查询字段 actions = [] # 批量删除 def patch_delete(self,request,queryset): queryset.delete() patch_delete.short_description = "Delete selected " def __init__(self,model, site): self.model = model self.site = site # 增删改查url def get_add_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_add" %(app_label,model_name)) return _url def get_list_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_list" %(app_label,model_name)) return _url # 复选框,编辑,删除 def checkbox(self,obj=None, header=False): if header: return mark_safe("<input id='choice' type='checkbox'>") return mark_safe("<input class='choice_item' type='checkbox' name='selected_pk' value='%s'>"%obj.pk) def edit(self,obj=None, header=False): if header: return "操作" # 方案1:固定url # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>") # 方案2:拼接url # return mark_safe("<a href='%s/change'>编辑</a>") # 方案3:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,)) # print("_url",_url) return mark_safe("<a href='%s'>编辑</a>"%_url) def deletes(self,obj=None, header=False): if header: return "操作" model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,)) return mark_safe("<a href='%s'>删除</a>"%_url) # ModelForm组件渲染 list、增、删、改页面 def get_modelform_class(self): """ModelForm组件""" if not self.modelform_class: from django.forms import ModelForm class ModelFormDemo(ModelForm): class Meta: model = self.model fields = "__all__" return ModelFormDemo else: return self.modelform_class def new_list_play(self): """构建 ['checkbox','pk', 'name', 'age', edit,'delete']""" temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) if not self.list_display_links: temp.append(ModelStark.edit) temp.append(ModelStark.deletes) return temp # action = ['delete',...] def new_actions(self): temp = [] temp.append(ModelStark.patch_delete) # delete添加 temp.extend(self.actions) # 如果定义新的,就扩展到temp中 return temp ''' def list_view(self,request): ret1 = self.model.objects.filter(title__startswith='py') ret2 = self.model.objects.filter(price__in=[11,22,33,44,55]) ret3 = self.model.objects.filter(price__range=[10,20]) ret4 = self.model.objects.filter(title__contains='O') ret5 = self.model.objects.filter(title__icontains='O') return HttpResponse("过滤成功") ''' def get_search_condition(self,request): """search模糊查询""" key_word = request.GET.get("q",'') self.key_word = key_word from django.db.models import Q # 与或非 search_connection = Q() if key_word: search_connection.connector = "or" for search_field in self.search_fields: search_connection.children.append((search_field+"__contains", key_word)) return search_connection def list_view(self, request): if request.method == 'POST': print('post',request.POST) action = request.POST.get("action") # action': ['patch_init'], if action: selected_pk = request.POST.getlist('selected_pk') # 'selected_pk': ['5']}> action_func = getattr(self,action) # 反射查询 action # 取出实例方法 queryset = self.model.objects.filter(pk__in=selected_pk) # 查询 ret = action_func(request,queryset) # 执行action() # 执行实例方法() # return ret # 获取search的Q对象 search_connection = self.get_search_condition(request) # 筛选获取当前表所有数据 data_list = self.model.objects.all().filter(search_connection) #按照showlist展示页面, 构建表头,表单 show_list = ShowList(self,data_list,request) # self=ModelSTark实例对象 # 构建一个查看addurl add_url = self.get_add_url() return render(request,'list_view.html', locals()) def add_view(self, request): ModelFormDemo=self.get_modelform_class() form = ModelFormDemo() if request.method == "POST": form = ModelFormDemo(request.POST) if form.is_valid(): form.save() return redirect(self.get_list_url()) return render(request, "add_view.html",locals()) def delete_view(self, request, id): url = self.get_list_url() if request.method == "POST": self.model.objects.filter(pk=id).delete() return redirect(url) return render(request, "delete_view.html", locals()) def change_view(self, request, id): edit_obj = self.model.objects.filter(pk=id).first() ModelFormDemo=self.get_modelform_class() form = ModelFormDemo(instance=edit_obj) if request.method == "POST": form = ModelFormDemo(request.POST,instance=edit_obj) if form.is_valid(): form.save() return redirect(self.get_list_url()) return render(request, "change_view.html",locals()) #构造 add/delete/change def get_urls2(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp = [] temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name))) temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name))) temp.append(url(r'^(\d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name))) temp.append(url(r'^(\d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name))) return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(object): """site单例类""" def __init__(self): self._registry = {} def register(self,model, stark_class=None): """注册""" if not stark_class: stark_class = ModelStark self._registry[model] = stark_class(model,self) def get_urls(self): """构造一层urls app01/book""" temp = [] for model, stark_class_obj in self._registry.items(): print(model, 'stark_clas_obj', stark_class_obj) # 不同的model模型表 """ <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198> <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240> """ app_label = model._meta.app_label # app01 model_name = model._meta.model_name # book # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None))) temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2)) """ path('app01/userinfo/',UserConfig(Userinfo,site).urls2), path('app01/book/',ModelStark(Book,site).urls2), """ return temp @property def urls(self): # return [],None,None return self.get_urls(),None,None site = StarkSite() # 单例对象
2、filter过滤
1、admin之过滤
2、多对多字段:data_list = filter_field_obj.remote_field.model.objects.all()
3、页面生成表单数据:多对多
4、filter过滤字段
5、filter字段的href动态变幻
6、加入普通字段的过滤字段
7、list_view视图获取数据
8、html模板层
3、总结+coding代码
1、总结
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())
data_list = filter_field_obj.remote_field.model.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)
7、获取页面的url中的filter字段,后面进行del,active样式
def get_filter_linktags(self):
link_dic = {}
for filter_field in self.config.list_filter: # ['title','publish','authors']
# 1.获取url中的相关字段,后面比较
current_id = self.request.GET.get(filter_field,0)
pararms = copy.deepcopy(self.request.GET)
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)
2、starkadmin.py
from django.shortcuts import HttpResponse from stark.service import stark from .models import * from django.forms import ModelForm class AuthorConfig(stark.ModelStark): list_display = ['nid', 'name', 'age'] list_display_links = ['name','age'] class BookModelForm(ModelForm): class Meta: model = Book fields = "__all__" labels = { "authors":"作者", "publishDate":"出版日期", } class BookConfig(stark.ModelStark): list_display = ['title', 'price','publish','authors'] list_display_links = ['title'] modelform_class = BookModelForm search_fields = ['title','price'] list_filter = ['title','publish','authors'] # 一对多,多对多字段 # 批量修改数据 def patch_init(self,request,queryset): queryset.update(price=111) # return HttpResponse("批量初始化OK") patch_init.short_description = "批量初始化" actions = [patch_init] stark.site.register(Book,BookConfig) stark.site.register(Publish) stark.site.register(Author,AuthorConfig) stark.site.register(AuthorDetail) # print(stark.site._registry)
3、stark/service/stark.py
# -*- coding: utf-8 -*- # @Time : 2018/08/17 0017 14:46 # @Author : Venicid from django.conf.urls import url from django.shortcuts import HttpResponse,render,redirect from django.utils.safestring import mark_safe from django.urls import reverse from django.db.models import Q # 与或非 from django.db.models.fields.related import ForeignKey from django.db.models.fields.related import ManyToManyField import copy from stark.utils.page import Pagination class ShowList(object): def __init__(self,config, data_list,request): self.config = config # MOdelStark实例对象 self.data_list = data_list # 数据 self.request =request # 分页 data_count = self.data_list.count() current_page = int(self.request.GET.get('page',1)) base_path = self.request.path self.pagination = Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=10, pager_count=11,) # 分页后的数据 self.page_data = self.data_list[self.pagination.start:self.pagination.end] # actions 批量初始化,字段 # self.actions = self.config.actions # [patch_init] self.actions = self.config.new_actions() # [pathch_delete,patch_init,] # 构建数据[{'name':'path_init',"desc":'xxxxx'}] # filter的tag如何生成的 def get_filter_linktags(self): link_dic = {} for filter_field in self.config.list_filter: # ['title','publish','authors'] # 1.获取url中的相关字段,后面比较 current_id = self.request.GET.get(filter_field,0) pararms = copy.deepcopy(self.request.GET) # 2 页面生成 各种字段 filter_field_obj = self.config.model._meta.get_field(filter_field) print(filter_field_obj,type(filter_field_obj)) # app01.Book.publish < class 'django.db.models.fields.related.ForeignKey'> # app01.Book.authors < class 'django.db.models.fields.related.ManyToManyField'> # print('rel...',filter_field_obj.re) # <ManyToOneRel: app01.book> # print('rel...',filter_field_obj.re.to.objects.all()) # <QuerySet [<Publish: 南京出版社>, <Publish: 北京出版社>]> # 解决步骤 # print('rel...',filter_field_obj.__dict__) # print('rel...',filter_field_obj.remote_field) # print('rel...',filter_field_obj.remote_field.__dict__) # print("rel...", filter_field_obj.remote_field.model.objects.all()) # <QuerySet [<Publish: 南京出版社>, <Publish: 北京出版社>]> # <QuerySet [<Author: jack>, <Author: tom>]> # 一对一字段or一对多字段 if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField): data_list = filter_field_obj.remote_field.model.objects.all() else: # 普通字段 data_list = self.config.model.objects.all().values('pk',filter_field) # 3、 生成标签的href temp = [] if pararms.get(filter_field): del pararms[filter_field] temp.append("<a href='?%s'>全部</a>"%pararms.urlencode()) else: temp.append("<a href='#' class='active'>全部</a>") # 处理filter字段的href for obj in data_list: # print(data_list) # 一对一,一对多字段 if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField): pk = obj.pk text = str(obj) pararms[filter_field] = pk else: # 普通字段 pk = obj.get('pk') text = obj.get(filter_field) pararms[filter_field] = text _url = pararms.urlencode() # print(type(current_id),type(pk),type(text)) if str(current_id) == str(pk) or str(current_id) ==str(text): link_tag = "<a href='?%s' class='active'>%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 def get_action_list(self): """action批量初始化,构架数据""" temp = [] for action in self.actions: temp.append( {'name':action.__name__, # class的类名 "desc":action.short_description # class的属性 } ) return temp def get_header(self): # 构建表头 header_list = [] # # header_list = ['选择','pk',...'操作','操作'] for field in self.config.new_list_play(): if callable(field): # header_list.append(field.__name__) val = field(self.config, header=True) header_list.append(val) else: if field == "__str__": header_list.append(self.config.model._meta.model_name.upper()) else: val = self.config.model._meta.get_field(field).verbose_name # 中文名称 header_list.append(val) return header_list def get_body(self): # 构建表单 new_data_list = [] for obj in self.page_data: #分页后的数据 # Book表模型,Author表模型 temp = [] for field in self.config.new_list_play(): # ['name','age'] if callable(field): # edit() 可调用的 # print(obj,99999999999999999) val = field(self.config,obj) # 直接调用edit()函数 # print('val--------->',val) else: from django.db.models.fields.related import ManyToManyField field_obj = self.config.model._meta.get_field(field) if isinstance(field_obj,ManyToManyField): ret = getattr(obj,field).all() # 反射 obj是实例对象,name是方法 t = [] for obj in ret: t.append(str(obj)) val = ','.join(t) else: val = getattr(obj, field) # list_display_links 按钮 if field in self.config.list_display_links: model_name = self.config.model._meta.model_name app_label = self.config.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) # print(_url) val = mark_safe("<a href='%s'>%s</a>"%(_url,val)) temp.append(val) new_data_list.append(temp) # print('new_data_list',new_data_list) # 构造数据 [['jack', 44], ['mark', 33]] return new_data_list class ModelStark(object): list_display = ["__str__"] # 子类中没有,直接用父类自己的 list_display_links = [] modelform_class = [] search_fields = [] # 模糊查询字段 actions = [] list_filter = [] # 过滤字段 # 批量删除 def patch_delete(self,request,queryset): queryset.delete() patch_delete.short_description = "Delete selected " def __init__(self,model, site): self.model = model self.site = site # 增删改查url def get_add_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_add" %(app_label,model_name)) return _url def get_list_url(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_list" %(app_label,model_name)) return _url # 复选框,编辑,删除 def checkbox(self,obj=None, header=False): if header: return mark_safe("<input id='choice' type='checkbox'>") return mark_safe("<input class='choice_item' type='checkbox' name='selected_pk' value='%s'>"%obj.pk) def edit(self,obj=None, header=False): if header: return "操作" # 方案1:固定url # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>") # 方案2:拼接url # return mark_safe("<a href='%s/change'>编辑</a>") # 方案3:反向解析 model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,)) # print("_url",_url) return mark_safe("<a href='%s'>编辑</a>"%_url) def deletes(self,obj=None, header=False): if header: return "操作" model_name = self.model._meta.model_name app_label = self.model._meta.app_label _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,)) return mark_safe("<a href='%s'>删除</a>"%_url) # ModelForm组件渲染 list、增、删、改页面 def get_modelform_class(self): """ModelForm组件""" if not self.modelform_class: from django.forms import ModelForm class ModelFormDemo(ModelForm): class Meta: model = self.model fields = "__all__" return ModelFormDemo else: return self.modelform_class def new_list_play(self): """构建 ['checkbox','pk', 'name', 'age', edit,'delete']""" temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) if not self.list_display_links: temp.append(ModelStark.edit) temp.append(ModelStark.deletes) return temp # action = ['delete',...] def new_actions(self): temp = [] temp.append(ModelStark.patch_delete) # delete添加 temp.extend(self.actions) # 如果定义新的,就扩展到temp中 return temp ''' def list_view(self,request): ret1 = self.model.objects.filter(title__startswith='py') ret2 = self.model.objects.filter(price__in=[11,22,33,44,55]) ret3 = self.model.objects.filter(price__range=[10,20]) ret4 = self.model.objects.filter(title__contains='O') ret5 = self.model.objects.filter(title__icontains='O') return HttpResponse("过滤成功") ''' def get_search_condition(self,request): """search模糊查询""" key_word = request.GET.get("q",'') self.key_word = key_word search_connection = Q() if key_word: search_connection.connector = "or" for search_field in self.search_fields: search_connection.children.append((search_field+"__contains", key_word)) return search_connection def get_filter_condition(self,request): """filter过滤处理""" filter_condition = Q() # 并且 for filter_field,val in request.GET.items(): if filter_field in self.list_filter: # list_filter = ['publish','authors'] filter_condition.children.append((filter_field,val)) return filter_condition def list_view(self, request): if request.method == 'POST': # print('post',request.POST) action = request.POST.get("action") # action': ['patch_init'], if action: selected_pk = request.POST.getlist('selected_pk') # 'selected_pk': ['5']}> action_func = getattr(self,action) # 反射查询 action # 取出实例方法 queryset = self.model.objects.filter(pk__in=selected_pk) # 查询 ret = action_func(request,queryset) # 执行action() # 执行实例方法() # return ret # 获取search的Q对象 search_connection = self.get_search_condition(request) # 获取filter构建Q对象 filter_condition = self.get_filter_condition(request) # 筛选获取当前表所有数据 # data_list = self.model.objects.all().filter(search_connection) data_list = self.model.objects.all().filter(search_connection).filter(filter_condition) #按照showlist展示页面, 构建表头,表单 show_list = ShowList(self,data_list,request) # self=ModelSTark实例对象 # 构建一个查看addurl add_url = self.get_add_url() return render(request,'list_view.html', locals()) def add_view(self, request): ModelFormDemo=self.get_modelform_class() form = ModelFormDemo() if request.method == "POST": form = ModelFormDemo(request.POST) if form.is_valid(): form.save() return redirect(self.get_list_url()) return render(request, "add_view.html",locals()) def delete_view(self, request, id): url = self.get_list_url() if request.method == "POST": self.model.objects.filter(pk=id).delete() return redirect(url) return render(request, "delete_view.html", locals()) def change_view(self, request, id): edit_obj = self.model.objects.filter(pk=id).first() ModelFormDemo=self.get_modelform_class() form = ModelFormDemo(instance=edit_obj) if request.method == "POST": form = ModelFormDemo(request.POST,instance=edit_obj) if form.is_valid(): form.save() return redirect(self.get_list_url()) return render(request, "change_view.html",locals()) #构造 add/delete/change def get_urls2(self): model_name = self.model._meta.model_name app_label = self.model._meta.app_label temp = [] temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name))) temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name))) temp.append(url(r'^(\d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name))) temp.append(url(r'^(\d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name))) return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(object): """site单例类""" def __init__(self): self._registry = {} def register(self,model, stark_class=None): """注册""" if not stark_class: stark_class = ModelStark self._registry[model] = stark_class(model,self) def get_urls(self): """构造一层urls app01/book""" temp = [] for model, stark_class_obj in self._registry.items(): # print(model, 'stark_clas_obj', stark_class_obj) # 不同的model模型表 """ <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198> <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240> """ app_label = model._meta.app_label # app01 model_name = model._meta.model_name # book # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None))) temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2)) """ path('app01/userinfo/',UserConfig(Userinfo,site).urls2), path('app01/book/',ModelStark(Book,site).urls2), """ return temp @property def urls(self): # return [],None,None return self.get_urls(),None,None site = StarkSite() # 单例对象
4、list_view.html
{% extends 'base.html' %} {% block title %} <title>list页面</title> {% endblock %} {% block css %} <style type="text/css"> .active { color: red !important; } .filter a { text-decoration: none; color: grey; } </style> {% endblock %} {% block content %} <div class="col-md-9"> <a class="btn btn-primary" href="{{ add_url }}">添加数据</a> {% if show_list.config.search_fields %} <form action="" method="get"> <input type="text" class="form-control" style="width: 30%;display: inline-block;margin-top: 8px" name="q" value="{{ show_list.config.key_word }}"> <button class="btn btn-success">submit</button> </form> {% endif %} <form action="" method="post"> {% csrf_token %} <select name="action" class="form-control" style="display: inline-block;width: 200px;margin: 8px 8px 8px 0;height: 35px;vertical-align: -2px"> <option value="">-------</option> {% for item in show_list.get_action_list %} <option value="{{ item.name }}">{{ item.desc }}</option> {% endfor %} </select> <button type="submit" class="btn btn-primary">Go</button> <table class="table table-bordered table-striped"> <tr> {% for header in show_list.get_header %} {# {% for header in header_list %}#} <th>{{ header }}</th> {% endfor %} </tr> {% for data in show_list.get_body %} {# {% for data in new_data_list %}#} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </table> </form> <nav> <ul class="pagination"> {{ show_list.pagination.page_html|safe }} </ul> </nav> </div> <div class="col-md-3"> <div class="filter"> {% for filter_field, linktags in show_list.get_filter_linktags.items %} <div class="well"> <p>{{ filter_field.upper }}</p> {% for link in linktags %} <p>{{ link|safe }}</p> {% endfor %} </div> {% endfor %} </div> </div> {% endblock %} {% block javascript %} <script type="text/javascript"> $('#choice').click(function () { if ($(this).prop('checked')) { //对象自身属性中是否具有指定的属性 $('.choice_item').prop("checked", true) } else { $('.choice_item').prop("checked", false) } }) </script> {% endblock %}