python全栈开发day85-查:数据表 数据头 增加列 展示多对多字段 反向解析编辑和删除按钮的url

直接上代码:

# 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()
# spark/service/sites.py
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)
# app01/stark.py
{% 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>
list_view1.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
分页器
原文地址:https://www.cnblogs.com/wuchenggong/p/9553954.html