一、数据列表

  设计查页面,主要展示两部分内容,表头部分和数据部分, 表头通过遍历list_display和默认要显示的编辑和删除字段。

1、数据构建

(1)service/stark.py,后台数据构建

class ModelStark(object):
    """定制配置类"""
    list_display = []

    def __init__(self, model, site):
        self.model = model
        self.site = site
    '''省略其他代码'''

    def list_view(self, request):
        print("self.model:", self.model)   # self.model: <class 'app01.models.UserInfo'>
        print("list_display", self.list_display)    # list_display ['pk', 'name', 'age']
        data_list = self.model.objects.all()  # 拿到对应表所有的对象

        new_data_list = []
        for obj in data_list:   # 所查询表中的一个个对象
            temp = []
            for field in self.list_display:  # field为一个个字段字符串
                val = getattr(obj, field)   # obj.name  obj.age
                temp.append(val)
          new_data_list.append(temp)

        return render(request, "list_view.html", locals())
        
    '''省略其他代码'''

(2)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">
</head>
<body>
<h4>数据列表</h4>
<div class="container">
    <div class="row">
        <div class="col-md-9">
            <table class="table table-bordered table-striped">
                <thead></thead>
                <tbody>
                    {% for data in new_data_list %}
                        <tr>
                            {% for item in data %}
                                <td>{{ item }}</td>
                            {% endfor %}
                        </tr>
                    {% endfor %}

                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

  显示效果:

  stark——查看页面编辑删除按钮

注意:

(1)由于UserConfig类是ModelStark类的子类,且两边都有list_display变量。

  如果list_display有值就按里面的字段展示,如果没有值按照默认的obj展示。

app01/stark.py:

# 自定义配置类
class UserConfig(ModelStark):   # UserConfig是ModelStark的一个子类
    list_display = ["pk", "name", "age"]

  根据父类子类关系,从调用者类里去找x,如果调用者中没有x,去父类找:

class A(object):
    x = 12

    def func(self):
        print(self.x)

class B(A):
    x = 5


b = B()
b.func()  # 5

(2)字符串找对象的属性,反射

data_list = self.model.objects.all()  # 拿到对应表所有的对象
new_data_list = []
for obj in data_list:   # 所查询表中的一个个对象
    temp = []
    for field in self.list_display:  # field为一个个字段字符串
        val = getattr(obj, field)   # obj.name  obj.age

        temp.append(val)

  new_data_list.append(temp)
 

  字符串不是变量名称,无法进行点字符串操作。

class Person(object):
    def __init__(self, name):
        self.name = name

alex = Person("alex")

s = "name"

# 直接alex.s  或者alex."name"都是取不到值的
print(getattr(alex, s))   # alex

2、编辑按钮构建

from django.conf.urls import url
from django.shortcuts import HttpResponse,render


class ModelStark(object):
    """定制配置类"""
    list_display = []

    def __init__(self, model, site):
        self.model = model
        self.site = site

    def add(self, request):
        return HttpResponse("add")

    def delete(self, request, id):
        return HttpResponse("delete")

    def change(self, request, id):
        return HttpResponse("change")

    def list_view(self, request):
        print("self.model:", self.model)   # self.model: <class 'app01.models.UserInfo'>

        print("list_display", self.list_display)    # list_display ['pk', 'name', 'age']

        data_list = self.model.objects.all()  # 拿到对应表所有的对象

        new_data_list = []
        for obj in data_list:   # 所查询表中的一个个对象
            temp = []
            for field in self.list_display:  # field为一个个字段字符串  ['pk', 'name', 'age', edit]
                if callable(field):   # 用于判断是否是函数,可调用的是方法,不可调用的是属性
                    val = field(self, obj)   # edit(self, obj)  obj是当前正在处理的这个记录
                else:
                    val = getattr(obj, field)   # 一定要是属性才能这么去调用, obj.name  obj.age

                temp.append(val)

            new_data_list.append(temp)

        return render(request, "list_view.html", locals())

    def get_urls_2(self):
        temp = []

        # 用name取别名app名+model名+操作名可以保证别名不会重复
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        temp.append(url(r"^add/", self.add, name="%s_%s_add" % (app_label, model_name)))
        temp.append(url(r"^(\d+)/delete/", self.delete, name="%s_%s_delete" % (app_label, model_name)))
        temp.append(url(r"^(\d+)/change/", self.change, 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 urls_2(self):
        return self.get_urls_2(), None, None  # [], None, None


class StarkSite(object):
    """site单例类"""
    def __init__(self):
        self._registry = {}

    def register(self, model, stark_class=None, **options):
        """注册"""
        if not stark_class:
            # 如果注册的时候没有自定义配置类,执行
            stark_class = ModelStark   # 配置类

        # 将配置类对象加到_registry字典中,键为模型类
        self._registry[model] = stark_class(model, self)   # _registry={'model':admin_class(model)}

    def get_urls(self):
        """构造一层url"""
        temp = []
        for model, stark_class_obj in self._registry.items():
            # model:一个模型表
            # stark_class_obj:当前模型表相应的配置类对象

            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.urls_2))
            """
               path('app01/userinfo/',UserConfig(Userinfo,site).urls2),
               path('app01/book/',ModelStark(Book,site).urls2),
            """

        return temp

    @property
    def urls(self):
        return self.get_urls(), None, None


site = StarkSite()    # 单例对象
/stark/service/stark.py

相关文章: