模拟Django的admin自定义stark组件

1、新建Django项目--新建app:app01和stark--在settings中配置app和数据库--在models.py中新建模型表--完成数据库迁移

2、在stark下的apps.py中:

from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules


class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        autodiscover_modules('stark')  # 在程序启动后、url路由分配之前去找到叫stark的app
View Code

3、在settings中配置stark:

4、在app01下新建stark.py文件,完成模型表注册:

from stark.service.stark import *
from django.utils.safestring import mark_safe
from django.urls import reverse
from .models import *


class UserInfoConfig(ModelStark):
    def edit(self, data_obj):
        """编辑"""
        model_name = self.model._meta.model_name  # 表名
        app_label = self.model._meta.app_label  # app名
        _url = reverse("%s_%s_edit" % (app_label, model_name), args=(data_obj.pk,))  # 反向解析 拿到url
        return mark_safe("<a href='%s'>编辑</a>" % _url)  # 防止转义

    def checkbox(self, data_obj):
        """每条记录前面插入一个选择框"""
        return mark_safe("<input type='checkbox'>")

    list_display = [checkbox, "name", "age", edit]


class BookConfig(ModelStark):
    list_display = ["title", "price", "pub_date"]


site.register(UserInfo, UserInfoConfig)
site.register(Book, BookConfig)

print("_registry:", site._registry)

"""
函数:函数中有多少个参数,就要传递多少各参数,不存在自动传参
方法:自动将调用对象作为第一个参数进行传递
"""
View Code

5、在stark下新建包service--service下新建stark.py文件:

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, delete_id):
        """删除记录"""
        return HttpResponse("delete")

    def edit(self, request, edit_id):
        """编辑"""
        return HttpResponse("edit")

    def show(self, request):
        """查看"""
        data_list = self.model.objects.all()  # 获取数据

        new_data_list = []
        if self.list_display:
            for data_obj in data_list:  # 数据对象
                temp = []
                for field in self.list_display:  # 字段名
                    if callable(field):  # 判断是否为函数
                        val = field(self, data_obj)
                    else:
                        val = getattr(data_obj, field)  # 通过反射获取字段对应的数据
                    temp.append(val)
                new_data_list.append(temp)

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

    def get_method(self):
        """增删改查url"""
        method_list = []
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        method_list.append(url(r'^add/', self.add, name="%s_%s_add" % (app_label, model_name)))
        method_list.append(url(r'^(d+)/delete/', self.delete, name="%s_%s_delete" % (app_label, model_name)))
        method_list.append(url(r'^(d+)/edit/', self.edit, name="%s_%s_edit" % (app_label, model_name)))
        method_list.append(url(r'^$', self.show, name="%s_%s_show" % (app_label, model_name)))
        return method_list

    @property
    def urls2(self):
        return self.get_method(), 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):
        """拼接url"""
        urls_list = []
        for model, stark_class_obj in self._registry.items():
            model_name = model._meta.model_name  # 模型表
            app_label = model._meta.app_label  # app名称
            print(model_name, app_label)
            # 添加url
            urls_list.append(url(r'^%s/%s/' % (app_label, model_name), stark_class_obj.urls2))
            """
           url(r'^app01/userinfo/', UserInfoConfig(UserInfo).urls2), 
           url(r'^app01/book/', ModelStark(Book).urls2), 
           """
        return urls_list

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


site = StarkSite()
View Code

6、templates下新建模板

7、全局urls.py:

from django.contrib import admin
from django.urls import path, include
from django.conf.urls import url
from stark.service import stark

urlpatterns = [
    path('admin/', admin.site.urls),

    # 自定义stark组件
    url('^stark/', stark.site.urls),
]
"""
admin源码:
1、注册
    admin.py  
        admin.site.register()
2、url设计
    在ModelStark中:
        self.model :用户当前访问的模型表
    
    查看页面:
        表头
        表数据
        search
        actions
        分页
        filter
    
    增删改(modelForm)
    
    pop功能
    
    作业:
        访问任何模型表时都有编辑、删除、选择框
        如果用户没有配置的list_display,如何显示数据
"""
View Code

原文地址:https://www.cnblogs.com/yanlin-10/p/9617425.html