一、分页
效果图
知识点
1.分页
{{ showlist.pagination.page_html|safe }}
2.page.py
class Pagination(object):
def __init__(self, current_page, all_count, base_url,params, per_page_num=8, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param base_url: 分页中显示的URL前缀
:param pager_count: 最多显示的页码个数
:param params: ? 后面携带得参数 request.GET
"""
...
注意:翻页时,http://127.0.0.1:8090/stark/app01/publish/?page=2&name=alice&age=18
每页需带上之前的参数。
import copy
params = copy.deepcopy(params)
params._mutable = True
self.params = params # self.params : {"page":77,"title":"python","nid":1}
self.params["page"] = i
self.params.urlencode() 将{"name":"alice","age":18} 转换成 name=alice&age=18
temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)
3.list_view 视图函数
表头,表数据,分页... 内容太多,封装在一个类里面专门用来展示数据。
# 展示数据
showlist = ShowList(self, data_list, request)
class ShowList(object):
def __init__(self):
pass
def get_header(self):
pass
def get_body(self):
pass
stark/utils/page.py
""" 自定义分页组件 """ class Pagination(object): def __init__(self, current_page, all_count, base_url,params, per_page_num=8, pager_count=11, ): """ 封装分页相关数据 :param current_page: 当前页 :param all_count: 数据库中的数据总条数 :param per_page_num: 每页显示的数据条数 :param base_url: 分页中显示的URL前缀 :param pager_count: 最多显示的页码个数 :param params: ? 后面携带得参数 request.GET """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num self.base_url = base_url # 总页码 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count # 最多显示页码数 self.pager_count_half = int((pager_count - 1) / 2) import copy params = copy.deepcopy(params) params._mutable = True self.params = params # self.params : {"page":77,"title":"python","nid":1} @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 如果总页码 < 11个: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 总页码 > 11 else: # 当前页如果<=页面上最多显示(11-1)/2个页码 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 当前页大于5 else: # 页码翻到最后 if (self.current_page + self.pager_count_half) > self.all_pager: pager_start = self.all_pager - self.pager_count + 1 pager_end = self.all_pager + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] self.params["page"] = 1 first_page = '<li><a href="%s?%s">首页</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一页</a></li>' else: self.params["page"] = self.current_page - 1 prev_page = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(prev_page) for i in range(pager_start, pager_end): # self.params : {"page":77,"title":"python","nid":1} self.params["page"] = i # {"page":72,"title":"python","nid":1} if i == self.current_page: temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,) else: temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一页</a></li>' else: self.params["page"] = self.current_page + 1 next_page = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(next_page) self.params["page"] = self.all_pager last_page = '<li><a href="%s?%s">尾页</a></li>' % (self.base_url, self.params.urlencode(),) page_html_list.append(last_page) return ''.join(page_html_list)
stark/service/stark.py
from django.conf.urls import url from django.shortcuts import HttpResponse, reverse, redirect, render from django.utils.safestring import mark_safe from django.urls import reverse from django.forms import ModelForm from stark.utils.page import Pagination class ShowList(object): def __init__(self, config, data_list, request): self.config = config self.data_list = data_list self.request = request # def __init__(self, current_page, # all_count, # base_url,params, # per_page_num=8, pager_count=11, ): # 分页 data_count = self.data_list.count() current_page = 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=3, pager_count=11) self.page_data = self.data_list[self.pagination.start:self.pagination.end] def get_header(self): # 构建表头 header_list = [] # header_list = ['选择','pk',...'操作','操作'] for field in self.config .new_list_play(): if callable(field): val = field(self.config, header=True) else: if field == "__str__": val = self.config .model._meta.model_name.upper() else: # 根据str 拿字段对象 取中文 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 data in self.page_data: temp = [] for field in self.config.new_list_play(): # ['title','price'] 字符串找对象得属性 反射 # print('field:', field) if callable(field): val = field(self.config, data) else: val = getattr(data, field) if field in self.config.list_display_links: _url = self.config.get_change_url(data) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) # [['yuan', 12], ['alex', 18], ['egon', 22]] return new_data_list class ModelStark(object): list_display = ["__str__"] list_display_links = [] modelform_class = [] def __init__(self, model, site): self.model = model self.site = site def edit(self, obj=None, header=False): if header: return "操作" _url = self.get_change_url(obj) return mark_safe("<a href='%s'>编辑</a>" % _url) def deletes(self, obj=None, header=False): if header: return '操作' _url = self.get_delete_url(obj) return mark_safe("<a href='%s'>删除</a>" % _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'>") def get_modelform_class(self): if not self.modelform_class: class ModelFormDemo(ModelForm): class Meta: model = self.model fields = "__all__" return ModelFormDemo else: return self.modelform_class 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, delete_id): url = self.get_list_url() if request.method == 'POST': self.model.objects.filter(pk=delete_id).delete() return redirect(url) return render(request, 'delete_view.html', locals()) def change_view(self, request, change_id): ModelFormDemo = self.get_modelform_class() edit_obj = self.model.objects.filter(pk=change_id).first() 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()) def new_list_play(self): temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) temp.append(ModelStark.edit) temp.append(ModelStark.deletes) return temp def get_change_url(self, obj): model_name = self.model._meta.model_name app_lable = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_lable, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj): 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 _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 list_view(self, request): data_list = self.model.objects.all() # 展示数据 showlist = ShowList(self, data_list, request) # 构建一个查看url add_url = self.get_add_url() return render(request, 'list_view.html',locals()) def get_urls2(self): temp = [] model_name = self.model._meta.model_name app_label = self.model._meta.app_label 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))) temp.append(url(r'^$', self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(object): 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): temp = [] # 模型表,配置类对象 for model, stark_class_obj in self._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label # 分发增删改查 temp.append(url(r'%s/%s/'%(app_label,model_name), stark_class_obj.urls2)) return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite()
list_view.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-1.12.4.min.js"></script> <style type="text/css"> </style> </head> <body> <h4>数据列表</h4> <div class="container"> <div class="row"> <div class="col-md-9"> <a href="{{ add_url }}" class="btn btn-primary">添加数据</a> <table class="table table-bordered table-striped"> <thead> <tr> {% for item in showlist.get_header %} <th>{{ item }}</th> {% endfor %} </tr> </thead> <tbody> {% for data in showlist.get_body %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> <nav> <ul class="pagination"> {{ showlist.pagination.page_html|safe }} </ul> </nav> </div> </div> </div> <script type="text/javascript"> $('#choice').click(function () { if($(this).prop('checked')){ $('.choice_item').prop('checked',true) }else{ $('.choice_item').prop('checked',false) } }) </script> </body> </html>
二、search - 模糊查询
效果图
知识点
1.判断用户是否配置,配置才显示search框, get查询
search_fields = ['title', 'price']
显示key_words{{ showlist.config.key_words }}
{% if showlist.config.search_fields %}
<form action="" class="pull-right">
<input type="text" name="q" value="{{ showlist.config.key_words }}"><button>submit</button>
</form>
{% endif %}
2.Q对象
# 获取search得Q对象
search_connection = self.get_search_condition(request)
# print("connection:",search_connection)
# connection: (or: ('title__contains', '3'), ('price__contains', '3'))
# 筛选当前表得所有数据
data_list = self.model.objects.all().filter(search_connection)
3.Q查询
两种方式,一种可以放str,就是下面这种,一种放字段;
def get_search_condition(self, request):
key_words = request.GET.get('q', "")
self.key_words = key_words
# self.search_fields ['title','price']
from django.db.models import Q
search_connection = Q()
if key_words:
search_connection.connector = "or"
for search_field in self.search_fields:
search_connection.children.append((search_field+"__contains", key_words))
return search_connection
4.模糊查询
(title__contains)(price__contains)
search_connection.children.append((search_field+"__contains", key_words))
stark/service/stark.py
from django.conf.urls import url from django.shortcuts import HttpResponse, reverse, redirect, render from django.utils.safestring import mark_safe from django.urls import reverse from django.forms import ModelForm from stark.utils.page import Pagination class ShowList(object): def __init__(self, config, data_list, request): self.config = config self.data_list = data_list self.request = request # 分页 data_count = self.data_list.count() current_page = 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=3, pager_count=11) self.page_data = self.data_list[self.pagination.start:self.pagination.end] def get_header(self): # 构建表头 header_list = [] # header_list = ['选择','pk',...'操作','操作'] for field in self.config .new_list_play(): if callable(field): val = field(self.config, header=True) else: if field == "__str__": val = self.config .model._meta.model_name.upper() else: # 根据str 拿字段对象 取中文 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 data in self.page_data: temp = [] for field in self.config.new_list_play(): # ['title','price'] 字符串找对象得属性 反射 # print('field:', field) if callable(field): val = field(self.config, data) else: val = getattr(data, field) if field in self.config.list_display_links: _url = self.config.get_change_url(data) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) # [['yuan', 12], ['alex', 18], ['egon', 22]] return new_data_list class ModelStark(object): list_display = ["__str__"] list_display_links = [] modelform_class = [] search_fields = [] def __init__(self, model, site): self.model = model self.site = site def edit(self, obj=None, header=False): if header: return "操作" _url = self.get_change_url(obj) return mark_safe("<a href='%s'>编辑</a>" % _url) def deletes(self, obj=None, header=False): if header: return '操作' _url = self.get_delete_url(obj) return mark_safe("<a href='%s'>删除</a>" % _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'>") def get_modelform_class(self): if not self.modelform_class: class ModelFormDemo(ModelForm): class Meta: model = self.model fields = "__all__" return ModelFormDemo else: return self.modelform_class 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, delete_id): url = self.get_list_url() if request.method == 'POST': self.model.objects.filter(pk=delete_id).delete() return redirect(url) return render(request, 'delete_view.html', locals()) def change_view(self, request, change_id): ModelFormDemo = self.get_modelform_class() edit_obj = self.model.objects.filter(pk=change_id).first() 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()) def new_list_play(self): temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) temp.append(ModelStark.edit) temp.append(ModelStark.deletes) return temp def get_change_url(self, obj): model_name = self.model._meta.model_name app_lable = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_lable, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj): 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 _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 get_search_condition(self, request): key_words = request.GET.get('q', "") self.key_words = key_words from django.db.models import Q search_connection = Q() if key_words: search_connection.connector = "or" for search_field in self.search_fields: search_connection.children.append((search_field+"__contains", key_words)) return search_connection def list_view(self, request): data_list = self.model.objects.all() # 获取searchd得Q对象 search_connection = self.get_search_condition(request) # print("connection:",search_connection) # connection: (or: ('title__contains', '3'), ('price__contains', '3')) # 筛选当前表得所有数据 data_list = self.model.objects.all().filter(search_connection) # 展示数据 showlist = ShowList(self, data_list, request) # 构建一个查看url add_url = self.get_add_url() return render(request, 'list_view.html',locals()) def get_urls2(self): temp = [] model_name = self.model._meta.model_name app_label = self.model._meta.app_label 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))) temp.append(url(r'^$', self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(object): 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): temp = [] # 模型表,配置类对象 for model, stark_class_obj in self._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label # 分发增删改查 temp.append(url(r'%s/%s/'%(app_label,model_name), stark_class_obj.urls2)) return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite()
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': '出版日期' } class BookConfig(stark.ModelStark): list_display = ['title', 'price','publishDate'] list_display_links = ['title'] modelform_class = BookModelForm search_fields = ['title', 'price'] stark.site.register(Book, BookConfig) stark.site.register(Publish) stark.site.register(Author) stark.site.register(AuthorDetail)
list_view.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-1.12.4.min.js"></script> <style type="text/css"> </style> </head> <body> <h4>数据列表</h4> <div class="container"> <div class="row"> <div class="col-md-9"> <a href="{{ add_url }}" class="btn btn-primary">添加数据</a> {% if showlist.config.search_fields %} <form action="" class="pull-right"> <input type="text" name="q" value="{{ showlist.config.key_words }}"><button>submit</button> </form> {% endif %} <table class="table table-bordered table-striped"> <thead> <tr> {% for item in showlist.get_header %} <th>{{ item }}</th> {% endfor %} </tr> </thead> <tbody> {% for data in showlist.get_body %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> <nav> <ul class="pagination"> {{ showlist.pagination.page_html|safe }} </ul> </nav> </div> </div> </div> <script type="text/javascript"> $('#choice').click(function () { if($(this).prop('checked')){ $('.choice_item').prop('checked',true) }else{ $('.choice_item').prop('checked',false) } }) </script> </body> </html>
三、actions - 批量处理
效果图
知识点
1.用户可自定义配置
def patch_init(self, request, queryset):
# print("queryset",queryset)
queryset.update(price=123)
# return HttpResponse('批量初始化OK')
patch_init.short_description = "批量初始化"
actions = [patch_init]
2.无论有没有配置,都会有一个默认得批量删除
def patch_delete(self, request, queryset):
queryset.delete()
patch_delete.short_description = "批量删除"
def new_actions(self):
temp = []
temp.append(ModelStark.patch_delete)
temp.extend(self.actions)
return temp
3.展示页面 option
传过去得数据: __name__ (方法名传过去,做为value,为之后反射做准备)
self.actions = self.config.new_actions()
def get_action_list(self):
temp = []
for action in self.actions:
temp.append({
"name": action.__name__,
"desc":action.short_description
})
return temp
4.前端
主要就是将:方法名赋值给option得value, form post请求,将值传到后台
<select name="action" id="" style="width: 200px; padding: 5px 8px; display: inline-block; ">
<option value="">------------</option>
{% for item in showlist.get_action_list %}
<option value="{{ item.name }}">{{ item.desc }}</option>
{% endfor %}
</select>
5.后台
接收用户选中得数据,action selected_pk
反射:action_func = getattr(self, action)
过滤查询:queryset: queryset = self.model.objects.filter(pk__in=selected_pk)
执行反射回来得函数: action_func(request, queryset)
def list_view(self, request):
if request.method == "POST":
print("request.POST:",request.POST)
# 'action': ['patch_init'], 'selected_pk': ['1', '2']
action = request.POST.get('action')
selected_pk = request.POST.getlist('selected_pk')
action_func = getattr(self, action) # 反射
queryset = self.model.objects.filter(pk__in=selected_pk) # 秒!!!
ret = action_func(request, queryset)
# return ret
...
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] stark.site.register(Book, BookConfig) stark.site.register(Publish) stark.site.register(Author) stark.site.register(AuthorDetail)
stark/service/stark.py
from django.conf.urls import url from django.shortcuts import HttpResponse, reverse, redirect, render from django.utils.safestring import mark_safe from django.urls import reverse from django.forms import ModelForm from stark.utils.page import Pagination class ShowList(object): def __init__(self, config, data_list, request): self.config = config self.data_list = data_list self.request = request # 分页 data_count = self.data_list.count() current_page = 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=3, pager_count=11) self.page_data = self.data_list[self.pagination.start:self.pagination.end] self.actions = self.config.new_actions() def get_action_list(self): temp = [] for action in self.actions: temp.append({ "name": action.__name__, "desc":action.short_description }) return temp def get_header(self): # 构建表头 header_list = [] # header_list = ['选择','pk',...'操作','操作'] for field in self.config .new_list_play(): if callable(field): val = field(self.config, header=True) else: if field == "__str__": val = self.config .model._meta.model_name.upper() else: # 根据str 拿字段对象 取中文 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 data in self.page_data: temp = [] for field in self.config.new_list_play(): # ['title','price'] 字符串找对象得属性 反射 # print('field:', field) if callable(field): val = field(self.config, data) else: val = getattr(data, field) if field in self.config.list_display_links: _url = self.config.get_change_url(data) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) # [['yuan', 12], ['alex', 18], ['egon', 22]] return new_data_list class ModelStark(object): list_display = ["__str__"] list_display_links = [] modelform_class = [] search_fields = [] actions = [] def __init__(self, model, site): self.model = model self.site = site def patch_delete(self, request, queryset): queryset.delete() patch_delete.short_description = "批量删除" def edit(self, obj=None, header=False): if header: return "操作" _url = self.get_change_url(obj) return mark_safe("<a href='%s'>编辑</a>" % _url) def deletes(self, obj=None, header=False): if header: return '操作' _url = self.get_delete_url(obj) return mark_safe("<a href='%s'>删除</a>" % _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 get_modelform_class(self): if not self.modelform_class: class ModelFormDemo(ModelForm): class Meta: model = self.model fields = "__all__" return ModelFormDemo else: return self.modelform_class 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, delete_id): url = self.get_list_url() if request.method == 'POST': self.model.objects.filter(pk=delete_id).delete() return redirect(url) return render(request, 'delete_view.html', locals()) def change_view(self, request, change_id): ModelFormDemo = self.get_modelform_class() edit_obj = self.model.objects.filter(pk=change_id).first() 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()) def new_list_play(self): temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) temp.append(ModelStark.edit) temp.append(ModelStark.deletes) return temp def new_actions(self): temp = [] temp.append(ModelStark.patch_delete) temp.extend(self.actions) return temp def get_change_url(self, obj): model_name = self.model._meta.model_name app_lable = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_lable, model_name), args=(obj.pk,)) return _url def get_delete_url(self, obj): 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 _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 get_search_condition(self, request): key_words = request.GET.get('q', "") self.key_words = key_words from django.db.models import Q search_connection = Q() if key_words: search_connection.connector = "or" for search_field in self.search_fields: search_connection.children.append((search_field+"__contains", key_words)) return search_connection def list_view(self, request): if request.method == "POST": print("request.POST:",request.POST) # 'action': ['patch_init'], 'selected_pk': ['1', '2'] action = request.POST.get('action') selected_pk = request.POST.getlist('selected_pk') action_func = getattr(self, action) # 反射 queryset = self.model.objects.filter(pk__in=selected_pk) # 秒!!! ret = action_func(request, queryset) # return ret # 获取searchd得Q对象 search_connection = self.get_search_condition(request) # 筛选当前表得所有数据 data_list = self.model.objects.all().filter(search_connection) # 展示数据 showlist = ShowList(self, data_list, request) # 构建一个查看url add_url = self.get_add_url() return render(request, 'list_view.html',locals()) def get_urls2(self): temp = [] model_name = self.model._meta.model_name app_label = self.model._meta.app_label 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))) temp.append(url(r'^$', self.list_view, name="%s_%s_list" % (app_label, model_name))) return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(object): 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): temp = [] # 模型表,配置类对象 for model, stark_class_obj in self._registry.items(): model_name = model._meta.model_name app_label = model._meta.app_label # 分发增删改查 temp.append(url(r'%s/%s/'%(app_label,model_name), stark_class_obj.urls2)) return temp @property def urls(self): return self.get_urls(), None, None site = StarkSite()
list_view.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> <script src="/static/js/jquery-1.12.4.min.js"></script> <style type="text/css"> </style> </head> <body> <h4>数据列表</h4> <div class="container"> <div class="row"> <div class="col-md-9"> <a href="{{ add_url }}" class="btn btn-primary">添加数据</a> {% if showlist.config.search_fields %} <form action="" class="pull-right"> <input type="text" name="q" value="{{ showlist.config.key_words }}"><button>submit</button> </form> {% endif %} <form action="" method="post"> {% csrf_token %} <select name="action" id="" style="width: 200px; padding: 5px 8px; display: inline-block; "> <option value="">------------</option> {% for item in showlist.get_action_list %} <option value="{{ item.name }}">{{ item.desc }}</option> {% endfor %} </select><button type="submit" class="btn btn-info">GO</button> <table class="table table-bordered table-striped"> <thead> <tr> {% for item in showlist.get_header %} <th>{{ item }}</th> {% endfor %} </tr> </thead> <tbody> {% for data in showlist.get_body %} <tr> {% for item in data %} <td>{{ item }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> <nav> <ul class="pagination"> {{ showlist.pagination.page_html|safe }} </ul> </nav> </form> </div> </div> </div> <script type="text/javascript"> $('#choice').click(function () { if($(this).prop('checked')){ $('.choice_item').prop('checked',true) }else{ $('.choice_item').prop('checked',false) } }) </script> </body> </html>