stark组件之delete按钮、filter过滤
- 1、构建批量删除按钮
- 2、filter过滤
- 3、总结+coding代码
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 %}
list_view.html
- 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>}
- """
starkadmin
- # -*- 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() # 单例对象
stark/service/stark.py
2、filter过滤
1、admin之过滤
2、多对多字段:data_list = filter_field_obj.remote_field.model.objects.all()
1.封装好一个Q对象
- # 得到过滤的字段,封装成一个"和"关系的Q对象返回。
- def get_filter_condition(self,request):
- from django.db.models import Q
- filter_condition=Q()
- 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
2.调用函数,传入request,然后加一个filter条件就可以了。
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 %}
stark组件之delete按钮、filter过滤的更多相关文章
- 11 stark组件之delete按钮、filter过滤
1.构建批量删除按钮 1.admin中每个页面默认都有 2.stark之构建批量删除 3.coding {% extends 'base.html' %} {% block title %} < ...
- stark组件之pop页面,按钮,url,页面
1.Window open() 方法 2.admin的pop添加按钮 3.stark之pop功能 3.知识点总结 4.coding代码 1.Window open() 方法 效果图 2.adm ...
- 12 stark组件之pop,按钮,url,页面
1.Window open() 方法 http://www.runoob.com/jsref/met-win-open.html 效果图 2.admin的pop添加按钮 3.stark之pop功能 ...
- day 69crm(6) stark组件 action 和 多层过滤效果
前情提要: 今天学的是stark 组件的 action 和多层过效果 一: action (自定制函数多选功能效果) 1: 学习 观点明确: 2: 多选效果前端和后端进行的操作 2& ...
- 【django之stark组件】
一.需求 仿照django的admin,开发自己的stark组件.实现类似数据库客户端的功能,对数据进行增删改查. 二.实现 1.在settings配置中分别注册这三个app # Applicatio ...
- django 之 stark组件
----------------------------------------------------------------烦恼没完没了,内心动荡不安,呜呼哀哉. 一.有个特殊的需求,需要用sta ...
- stark组件的分页,模糊查询,批量删除
1.分页组件高阶 2.整合展示数据showlist类 3.stark组件之分页 3.stark组件之search模糊查询 4.action批量处理数据 4.总结 1.分页组件高阶 1.分页的class ...
- stark组件之创建
stark组件之需求 仿照Django中的admin , 开发了自己的stark组件,实现类似数据库客户端的功能,对数据进行增删改查 . stark之创建 1.在项目中 创建stark应用,app01 ...
- crm项目-stark组件
############### admin基本认识和常用的定制功能 ############### stark组件 对admin的基本认识 1,就是一个app,嵌入到了django里面,你可以 ...
随机推荐
- centOS7docker安装oracle
1.拉取oracle 11g 的镜像: 用root登陆服务器,输入下面的命令,拉取oracle 11g的镜像,有点大,6.8G多: docker pull registry.cn-hangzhou.a ...
- June 18. 2018, Week 25th. Monday
Health and cheerfulness naturally beget each other. 安康喜乐,相生相成. From Joseph Addison. Good health is a ...
- Spring的AOP基于AspectJ的注解方式开发3
上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...
- js格式化输入框内金额、银行卡号[转]
这篇文章主要介绍了js格式化输入框内金额.银行卡号,采用“keyup”事件处理格式化,每4位数一组中间空格隔开,如何格式化输入框内金额.银行卡号,需要了解的朋友可以参考一下 我们在项目中经常遇到需要格 ...
- D. Equalize Them All Codeforces Round #550 (Div. 3)
D. Equalize Them All time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- django ORM的总结
1.django分表的方案: https://mp.weixin.qq.com/s?__biz=MjM5NjA3Nzk3Ng==&mid=2648154502&idx=1& ...
- centos7下如何隐藏nginx的版本号
我们在访问nginx的时候会暴露nginx的版本号,如何将这些版本号隐藏呢? 其实隐藏版本号非常简单 在nginx的配置文件中添加一个server——tokens off:参数就可以了,下面进行操作 ...
- P1553 数字反转(升级版)(模拟)
花了2个小时,写的..mmp只想说,还是我太菜了. #include<iostream> #include<cstring> using namespace std; ]; i ...
- Nginx 反向代理 -- 一路上的坑转载
个人学习之用转子https://www.cnblogs.com/xjbBill/p/7477825.html 前些天刚过来新公司上班,公司的项目都挺多的,只不过项目都是第三方公司团队开发的,现在本公司 ...
- 【vue】vue +element prop用法
简单demo 父组件:index.vue <template> <div class="app-container"> <vue-props-demo ...