• strak组件(6):列表定制列应用和引入静态文件


    效果图:

    新增函数

    def get_choice_text(title, field)   闭包函数,显示choice字段
        def inner(self, obj=None, is_header=None)
    
     def display_edit(self, obj=None, is_header=None)  显示编辑
     def display_delete(self, obj=None, is_header=None) 显示删除

    一、Model

    web/models.py

    class UserInfo(models.Model):
        """
        用户表
        """
        MALE = 1
        FEMALE = 2
        GENDER_CHOICES = (
            (MALE, ''),
            (FEMALE, ''),
        )
        CLASSES_CHOICES = (
            (1, 'python一班'),
            (2, 'python二班'),
        )
        name = models.CharField(verbose_name='姓名', max_length=32)
        age = models.CharField(verbose_name='年龄', max_length=32)
        email = models.CharField(verbose_name='邮箱', max_length=32)
        gender = models.PositiveIntegerField(verbose_name='性别', choices=GENDER_CHOICES, default=MALE)
        classes = models.PositiveIntegerField(verbose_name='班级', choices=CLASSES_CHOICES, default=1)
        department = models.ForeignKey(verbose_name='部门', to='Department', on_delete=models.CASCADE)
    
        def __str__(self):
            return self.name

    二、stark

    stark/service/core_func.py

    from types import FunctionType
    
    from django.urls import re_path
    from django.utils.safestring import mark_safe
    from django.shortcuts import HttpResponse, render, reverse
    
    
    def get_choice_text(title, field):
        """
        对于Stark组件中定义列时,choice如果想要显示中文信息,调用此方法即可。
        :param title: 希望页面显示的表头
        :param field:  字段名称
        :return:
        """
    
        def inner(self, obj=None, is_header=None):
            if is_header:
                return title
            method = "get_%s_display" % field
            return getattr(obj, method)()
            # GENDER_CHOICES = ((MALE, '男'),(FEMALE, '女'),)
            # 对于choice字段,如果想获取获取第二个值,可以通过:对象.get_字段名_display()
        return inner
    
    
    class StarkHandler(object):
        list_display = []
    
        def __init__(self, site, model_class, prev):
            self.site = site
            self.model_class = model_class
            self.prev = prev
    
        def display_edit(self, obj=None, is_header=None):
            """
            自定义页面显示的列(表头和内容)
            :param obj:
            :param is_header:
            :return:
            """
            if is_header:
                return '编辑'
            name = '%s:%s' % (self.site.namespace, self.get_edit_url_name,)
            return mark_safe('<a href="%s">编辑</a>' % reverse(name, args=(obj.pk,)))
    
        def display_delete(self, obj=None, is_header=None):
            if is_header:
                return '删除'
            name = '%s:%s' % (self.site.namespace, self.get_delete_url_name,)
            return mark_safe('<a href="%s">删除</a>' % reverse(name, args=(obj.pk,)))
    
        def get_list_display(self):
            """
            获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的列
            :return:
            """
            value = []
            value.extend(self.list_display)
            return value
    
        def list_view(self, request):
            """
            列表页面
            :param request:
            :return:
            """
    
            list_display = self.get_list_display()  # 会优先调用UserInfoHandler里的get_list_display()方法。
            # 1. 处理表格的表头
            header_list = []
            if list_display:
                for field_or_func in list_display:
                    if isinstance(field_or_func, FunctionType):
                        verbose_name = field_or_func(self, obj=None, is_header=True)
                    else:
                        verbose_name = self.model_class._meta.get_field(field_or_func).verbose_name
                    header_list.append(verbose_name)
            else:
                header_list.append(self.model_class._meta.model_name)  # 如果用户没有填写list_display,就显示表名
    
            # 2. 处理表的内容
            data_list = self.model_class.objects.all()
            body_list = []
            for obj in data_list:
                tr_list = []
                if list_display:
                    for field_or_func in list_display:
                        if isinstance(field_or_func, FunctionType):
                            tr_list.append(field_or_func(self, obj, is_header=False))
                        else:
                            tr_list.append(getattr(obj, field_or_func))
                else:
                    tr_list.append(obj)  # 如果用户没有填写list_display,就显示表对象,所以表类要定义__str__方法
                body_list.append(tr_list)
    
            context = {
                'data_list': data_list,
                'header_list': header_list,
                'body_list': body_list,
            }
    
            return render(request, 'stark/data_list.html', context)
    
        def add_view(self, request):
            """
            添加页面
            :param request:
            :return:
            """
            return HttpResponse('添加页面')
    
        def edit_view(self, request, pk):
            """
            编辑页面
            :param request:
            :return:
            """
            return HttpResponse('编辑页面')
    
        def delete_view(self, request, pk):
            """
            删除页面
            :param request:
            :param pk:
            :return:
            """
            return HttpResponse('删除页面')
    
        def get_url_name(self, params):
            app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
            if self.prev:
                return '%s_%s_%s_%s' % (app_label, model_name, self.prev, params)
            return '%s_%s_%s' % (app_label, model_name, params)
    
        @property
        def get_list_url_name(self):
            """
            获取列表页面URL的name
            :return:
            """
            return self.get_url_name('list')
    
        @property
        def get_add_url_name(self):
            """
            获取添加页面URL的name
            :return:
            """
            return self.get_url_name('add')
    
        @property
        def get_edit_url_name(self):
            """
            获取编辑页面URL的name
            :return:
            """
            return self.get_url_name('edit')
    
        @property
        def get_delete_url_name(self):
            """
            获取删除页面URL的name
            :return:
            """
            return self.get_url_name('delete')
    
        def get_urls(self):
            patterns = [
                re_path(r'^list/$', self.list_view, name=self.get_list_url_name),
                re_path(r'^add/$', self.add_view, name=self.get_add_url_name),
                re_path(r'^edit/(d+)/$', self.edit_view, name=self.get_edit_url_name),
                re_path(r'^delete/(d+)/$', self.delete_view, name=self.get_delete_url_name),
            ]
    
            patterns.extend(self.extra_urls())
            return patterns
    
        def extra_urls(self):
            return []
    
    
    class StarkSite(object):
        def __init__(self):
            self._registry = []
            self.app_name = 'stark'
            self.namespace = 'stark'
    
        def register(self, model_class, handler_class=None, prev=None):
            """
            :param model_class: 是models中的数据库表对应的类。
            :param handler_class: 处理请求的视图函数所在的类
            :param prev: 生成URL的前缀
            :return:
            """
    
            if not handler_class:
                handler_class = StarkHandler
            self._registry.append(
                {'model_class': model_class, 'handler': handler_class(self, model_class, prev), 'prev': prev})
    
        def get_urls(self):
            patterns = []
            for item in self._registry:
                model_class = item['model_class']
                handler = item['handler']
                prev = item['prev']
                app_name, model_name = model_class._meta.app_label, model_class._meta.model_name
                if prev:
                    patterns.append(
                        re_path(r'^%s/%s/%s/' % (app_name, model_name, prev,), (handler.get_urls(), None, None)))
                else:
                    patterns.append(re_path(r'^%s/%s/' % (app_name, model_name,), (handler.get_urls(), None, None)))
    
            return patterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
    
    
    site = StarkSite()

    三、业务处理

    web/stark.py

    from stark.service.core_func import site, StarkHandler, get_choice_text
    
    from web import models
    
    
    class DepartmentHandler(StarkHandler):
        list_display = ['title']
    
    
    class UserInfoHandler(StarkHandler):
        list_display = [
            'name',
            get_choice_text('性别', 'gender'),
            get_choice_text('班级', 'classes'),
            'age', 'email', 'department',
            StarkHandler.display_edit,
            StarkHandler.display_delete,
    
        ]
    
    
    site.register(models.Department, DepartmentHandler) 
    site.register(models.UserInfo, UserInfoHandler)

    四、引入静态文件

    引入了bootstrap

    stark/templates/layout.html

    {% load staticfiles %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Strak组件</title>
        <link rel="shortcut icon" href="{% static 'stark/imgs/luffy-study-logo.png' %} ">
        <link rel="stylesheet" href="{% static 'stark/plugins/bootstrap/css/bootstrap.css' %} "/>
        <link rel="stylesheet" href="{% static 'stark/plugins/font-awesome/css/font-awesome.css' %} "/>
        <link rel="stylesheet" href="{% static 'stark/css/commons.css' %} "/>
        <link rel="stylesheet" href="{% static 'stark/css/nav.css' %} "/>
        <style>
            body {
                margin: 0;
            }
    
            .no-radius {
                border-radius: 0;
            }
    
            .no-margin {
                margin: 0;
            }
    
            .pg-body > .left-menu {
                background-color: #EAEDF1;
                position: absolute;
                left: 1px;
                top: 48px;
                bottom: 0;
                width: 220px;
                border: 1px solid #EAEDF1;
                overflow: auto;
            }
    
            .pg-body > .right-body {
                position: absolute;
                left: 225px;
                right: 0;
                top: 48px;
                bottom: 0;
                overflow: scroll;
                border: 1px solid #ddd;
                border-top: 0;
                font-size: 13px;
                min-width: 755px;
            }
    
            .navbar-right {
                float: right !important;
                margin-right: -15px;
            }
    
            .custom-container {
                padding: 15px;
            }
    
    
        </style>
    
        {% block css %}{% endblock %}
    </head>
    <body>
    
    <div class="pg-header">
        <div class="nav">
            <div class="logo-area left ">
                <a href="#">
                    <img class="logo" src="{% static 'stark/imgs/logo.svg' %}">
                    <span style="font-size: 18px;">Strak组件</span>
                </a>
            </div>
    
            <div class="left-menu left">
                <a class="menu-item">学生管理</a>
                <a class="menu-item">教师管理</a>
                <a class="menu-item">班级管理</a>
                <div class="menu-item">
                    <span>使用说明</span>
                    <i class="fa fa-caret-down" aria-hidden="true"></i>
                    <div class="more-info">
                        <a href="#" class="more-item">管他什么菜单</a>
                        <a href="#" class="more-item">实在是编不了</a>
                    </div>
                </div>
            </div>
    
            <div class="right-menu right clearfix">
    
                <div class="user-info right">
                    <a href="#" class="avatar">
                        <img class="img-circle" src="{% static 'stark/imgs/default.png' %}">
                    </a>
    
                    <div class="more-info">
                        <a href="#" class="more-item">个人信息</a>
                        <a href="#" class="more-item">注销</a>
                    </div>
                </div>
    
                <a class="user-menu right">
                    消息
                    <i class="fa fa-commenting-o" aria-hidden="true"></i>
                    <span class="badge bg-success">2</span>
                </a>
    
                <a class="user-menu right">
                    通知
                    <i class="fa fa-envelope-o" aria-hidden="true"></i>
                    <span class="badge bg-success">2</span>
                </a>
    
                <a class="user-menu right">
                    任务
                    <i class="fa fa-bell-o" aria-hidden="true"></i>
                    <span class="badge bg-danger">4</span>
                </a>
            </div>
    
        </div>
    </div>
    <div class="pg-body">
        <div class="left-menu">
            <div class="menu-body">
    
            </div>
        </div>
        <div class="right-body">
            <div>
    
            </div>
            {% block content %} {% endblock %}
        </div>
    </div>
    
    
    <script src="{% static 'stark/js/jquery-3.3.1.min.js' %} "></script>
    <script src="{% static 'stark/plugins/bootstrap/js/bootstrap.js' %} "></script>
    
    {% block js %} {% endblock %}
    </body>
    </html>

    stark/templates/stark/data_list.html

    {% extends 'layout.html' %}
    
    
    {% block content %}
        <div class="custom-container">
            <table class="table table-bordered">
                <thead>
                <tr>
                    {% for item in header_list %}
                        <th>{{ item }}</th>
                    {% endfor %}
                </tr>
                </thead>
                <tbody>
                {% for row in body_list %}
                    <tr>
                        {% for ele in row %}
                            <td>{{ ele }}</td>
                        {% endfor %}
    
                    </tr>
                {% endfor %}
    
                </tbody>
            </table>
        </div>
    {% endblock content %}

  • 相关阅读:
    MS面试归来:)
    准备出发到成都
    线程的同步机制(zz)
    Windows Vista(zz)
    这几天上海热晕了
    微软官方:Vista硬件要求指南(zz)
    有趣的递归缩写(Recursive acronym)
    《三国志》生僻人名读法集(zz)
    Git bash常用命令
    各大输入法分类词库内部格式的简单比较
  • 原文地址:https://www.cnblogs.com/lshedward/p/10566501.html
Copyright © 2020-2023  润新知