直接上代码:
# spark/service/sites.py from django.conf.urls import url from django.shortcuts import HttpResponse, render from django.urls import reverse from django.utils.safestring import mark_safe class ModelStark(object): def __init__(self, model): self.model = model self.model_name = self.model._meta.model_name self.app_label = self.model._meta.app_label self.list_display += ModelStark.extra_display def edit(self, obj=None, is_header=None): if is_header: return '编辑' name = "{}_{}_change".format(obj._meta.app_label, obj._meta.model_name) url = reverse(name, args=(obj.pk,)) return mark_safe("<a href='{}'>编辑</a>".format(url)) def delete(self, obj=None, is_header=None): if is_header: return '删除' name = "{}_{}_delete".format(obj._meta.app_label, obj._meta.model_name) url = reverse(name, args=(obj.pk,)) return mark_safe("<a href='{}'>删除</a>".format(url)) extra_display = [edit, delete] list_display = ["__str__"] def list_view(self, request): # 浏览器标题 name = self.model_name # 获取数据头 header_list = [] for field_or_func in self.list_display: # 判断如果是默认配置类的list_display,则数据头为模型表名大写 if field_or_func == '__str__': header_list.append(self.model_name.upper()) elif callable(field_or_func): header_list.append(field_or_func(self=self, is_header=True)) else: field_obj = self.model._meta.get_field(field_or_func) header_list.append(field_obj.verbose_name) # 分页器 from utils.pagenator import Pagenation current_page = request.GET.get('page') if not current_page: current_page = 1 base_url = request.path_info total_books_num = self.model.objects.all().count() my_pagenator = Pagenation(current_page=current_page, base_url=base_url, books_per_page=10, max_show=7, total_books_num=total_books_num) page_html = my_pagenator.page_html start = my_pagenator.start end = my_pagenator.end one_page_data_list = self.model.objects.all()[start:end] # 获取数据表所需数据 new_data_list = [] from django.db.models.fields.related import ManyToManyField for obj in one_page_data_list: temp = [] for field_or_func in self.list_display: if callable(field_or_func): val = field_or_func(self, obj=obj) elif field_or_func == '__str__': val = getattr(obj, field_or_func) else: field_obj = self.model._meta.get_field(field_or_func) if isinstance(field_obj, ManyToManyField): many_queryset = getattr(obj, field_or_func).all() val = '|'.join([str(item) for item in many_queryset]) else: val = getattr(obj, field_or_func) temp.append(val) new_data_list.append(temp) return render(request, 'list_view1.html', locals()) def add_view(self, request): return HttpResponse('add_view') def change_view(self, request, pk): return HttpResponse('change_view') def del_view(self, request, pk): return HttpResponse('del_view') def get_urls(self): tmp = [] tmp.append(url(r'^$', self.list_view, name="{}_{}_list".format(self.app_label, self.model_name))) tmp.append(url(r'add/$', self.add_view, name="{}_{}_add".format(self.app_label, self.model_name))) tmp.append(url(r'(d+)/delete/$', self.del_view, name="{}_{}_delete".format(self.app_label, self.model_name))) tmp.append( url('(d+)/change/$', self.change_view, name="{}_{}_change".format(self.app_label, self.model_name))) return tmp, None, None @property def urls(self): return self.get_urls() class AdminSite(object): def __init__(self): self._registy = {} def register(self, model, stark_class=None): if not stark_class: stark_class = ModelStark self._registy[model] = stark_class(model) def get_urls(self): tmp = [] for model, config_obj in self._registy.items(): tmp.append(url(r"{}/{}/".format(model._meta.app_label, model._meta.model_name), config_obj.urls)) return tmp, None, None @property def urls(self): return self.get_urls() site = AdminSite()
from stark.service.sites import site, ModelStark from app01 import models from django.utils.safestring import mark_safe from django.urls import reverse print('app01................') class BookStark(ModelStark): list_display = ['title', 'price', 'publisher', 'authors', ] site.register(models.Book, BookStark) site.register(models.Publish)
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ name }}</title> <link rel="stylesheet" href="{% static 'css/bootstrap.css' %}"> {# <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">#} </head> <body> <div class="container"> <div class="row"> <div class="col-md-8"> <table class="table table-bordered"> <thead> <tr> {% for list in header_list %} <th> {{ list }} </th> {% endfor %} </tr> </thead> <tbody> {% for data in new_data_list %} <tr> {% for field in data %} <td>{{ field }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> <div> {{ page_html|safe }} </div> </div> </div> </div> </body> </html>
from django.shortcuts import render, redirect class Pagenation(): def __init__(self, current_page, base_url, books_per_page, max_show, total_books_num): """ :param current_page: 当前访问页面,从request.GET.get('page',1)中获取 :param base_url: 需要访问的url地址 :param books_per_page: 每页显示几条数据 :param max_show: #最多显示几个分页 :param total_books_num: # 传入总计多少条数据记录 """ self.current_page = current_page self.base_url = base_url self.books_per_page = books_per_page self.max_show = max_show self.total_books_num = total_books_num self.__data_start = 0 self.__data_end = 0 self.page_html @property def start(self): """ :return: 返回切片数据的开始位置 """ return self.__data_start @property def end(self): """ 返回切片数据的结束位置 :return: """ return self.__data_end @property def page_html(self): """ :return: 返回分页的HTML代码,如果访问不在1~最大页码范围则返回redirect对象,引用的时候要注意。+ """ page_start = 0 page_end = 0 if self.total_books_num <= 0: return '没有数据!' total_pages_num, mod = divmod(self.total_books_num, self.books_per_page) if mod: total_pages_num = total_pages_num + 1 try: current_page = int(self.current_page) except: current_page = 1 half_num = self.max_show // 2 if current_page <= 0: current_page = 1 # return redirect('{}?page={}'.format(self.base_url, 1)) elif current_page > total_pages_num: current_page = total_pages_num # return redirect('{}?page={}'.format(self.base_url, total_pages_num)) if current_page <= half_num: page_start = 1 if total_pages_num >= self.max_show: page_end = self.max_show else: page_end = total_pages_num else: if current_page + half_num > total_pages_num: page_end = total_pages_num if total_pages_num > self.max_show: page_start = total_pages_num - self.max_show + 1 else: page_start = 1 else: page_start = current_page - half_num page_end = current_page + half_num self.__data_start = (current_page - 1) * self.books_per_page self.__data_end = current_page * self.books_per_page page_html_list = [] ul_start = '<ul class="pagination">' page_html_list.append(ul_start) previous_page = '<li class ="enable"><a href="{}?page={}" aria-label="Previous">' '<span aria-hidden="true"> « </span> </a> </li>'.format(self.base_url, current_page - 1) page_html_list.append(previous_page) first_page = '<li> <a href = "{}?page=1"> 首页 </a> </li>'.format(self.base_url) page_html_list.append(first_page) for i in range(page_start, page_end + 1): if i == current_page: li = '<li class="active"> <a href="{}?page={}">{}</a> </li>'.format(self.base_url, i, i) else: li = '<li> <a href="{}?page={}">{}</a> </li>'.format(self.base_url, i, i) page_html_list.append(li) end_page = '<li> <a href="{}?page={}">尾页</a> </li>'.format(self.base_url, total_pages_num) page_html_list.append(end_page) last_page = '<li class ="enable"><a href="{}?page={}" aria-label="Next">' '<span aria-hidden="true"> » </span> </a> </li>'.format(self.base_url, current_page + 1) page_html_list.append(last_page) ul_end = '</ul>' page_html_list.append(ul_end) page_html = ''.join(page_html_list) return page_html