zoukankan      html  css  js  c++  java
  • 模拟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

  • 相关阅读:
    【题解】Luogu P3217 [HNOI2011]数矩形
    【题解】 Luogu P4312 / SP4155 [COCI 2009] OTOCI / 极地旅行社
    珂朵莉树详解
    数学手法之线性基
    【题解】luogu P3386 【模板】二分图匹配
    【题解】Luogu P2146 [NOI2015]软件包管理器
    css 垂直居中方法汇总
    css3中什么时候用transition什么时候用animation实现动画
    前端进阶(8)
    前端进阶(12)
  • 原文地址:https://www.cnblogs.com/yanlin-10/p/9617425.html
Copyright © 2011-2022 走看看