• stark组件开发之自动生成URL


    创建一个新的django project,新建3个app并进行注册(app01/app02/stark)

    luffy_stark/settings.py

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
        'app02.apps.App02Config',
        'stark.apps.StarkConfig',
    ]

    创建基础业务表

    app01/models.py

    from django.db import models
    
    # Create your models here.
    
    
    class Depart(models.Model):
        """部门表"""
        title = models.CharField(
            verbose_name="部门名称",
            max_length=32,
        )
    
    
    class UserInfo(models.Model):
        """用户表"""
        name = models.CharField(
            verbose_name="姓名",
            max_length=32,
        )
        age = models.CharField(
            verbose_name="年龄",
            max_length=32,
        )
        email = models.CharField(
            verbose_name="邮箱",
            max_length=32,
        )
        depart = models.ForeignKey(
            verbose_name="部门",
            to="Depart",
            on_delete=models.CASCADE,
        )

    app02/models.py

    from django.db import models
    
    # Create your models here.
    
    
    class Host(models.Model):
        """主机表"""
        host = models.CharField(
            verbose_name="主机名称",
            max_length=32,
        )
        ip = models.GenericIPAddressField(
            verbose_name="ip",
            protocol="both",
        )

    在stark app下的apps.py中书写ready方法

    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")

    在stark app下的service目录下的v1.py书写一个类,该类有4个方法,第一个__init__初始化方法为实例绑定了3个变量,第二个register方法为每个models中的数据表类及处理请求的视图函数的类构建成一个字典放入到实例变量中的列表,第三个get_urls方法自动为每个models中的数据表类生成URL并绑定对应的视图函数,数据格式为路由格式,添加到一个列表中,第四个urls方法返回一个含有3个元素的元组,第一个元素为get_urls方法返回的列表,该列表有子路由,第二个元素为实例变量所定义的app_name,第三个元素为实例变量所定义的namespace

    stark/service/v1.py

    from django.urls import re_path
    
    
    class StarkSite(object):
        def __init__(self):
            self._registry = []
            self.app_name = "stark"
            self.namespace = "stark"
    
        def register(self, model_class, handler_class):
            """
            :param model_class: 是models中的数据库相关的类
            :param handler_class: 处理请求的视图函数所在的类
            :return:
            """
            self._registry.append({"model_class": model_class, "handler_class": handler_class(model_class),})
            """
            self._registry = [
                {"model_class": models.Depart, "handler_class": DepartHandler(models.Depart)},
                {"model_class": models.UserInfo, "handler_class": UserInfoHandler(models.UserInfo)},
                {"model_class": models.Host, "handler_class": HostHandler(models.Host)},
            ]
            """
    
        def get_urls(self):
            patterns = []
            for item in self._registry:
                model_class = item["model_class"]
                handler = item["handler_class"]
                # model_class._meta.app_label = app01/app01/app02/app02
                # model_class._meta.model_name = depart/userinfo/host/role
                app_label, model_name = model_class._meta.app_label, model_class._meta.model_name
                patterns.append(re_path(r'^%s/%s/list/$' % (app_label, model_name), handler.changelist_view),)
                patterns.append(re_path(r'^%s/%s/add/$' % (app_label, model_name), handler.add_view),)
                patterns.append(re_path(r'^%s/%s/change/(\d+)/$' % (app_label, model_name), handler.change_view),)
                patterns.append(re_path(r'^%s/%s/del/(\d+)/$' % (app_label, model_name), handler.delete_view),)
            return patterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
    
    
    site = StarkSite()
    
    """
    patterns = [
            <URLPattern '^app01/depart/list/$'>,
            <URLPattern '^app01/depart/add/$'>,
            <URLPattern '^app01/depart/change/(\d+)/$'>,
            <URLPattern '^app01/depart/del/(\d+)/$'>,
            <URLPattern '^app01/userinfo/list/$'>,
            <URLPattern '^app01/userinfo/add/$'>,
            <URLPattern '^app01/userinfo/change/(\d+)/$'>,
            <URLPattern '^app01/userinfo/del/(\d+)/$'>,
            <URLPattern '^app02/host/list/$'>,
            <URLPattern '^app02/host/add/$'>,
            <URLPattern '^app02/host/change/(\d+)/$'>,
            <URLPattern '^app02/host/del/(\d+)/$'>,
    ]
    """

    app01/stark.py

    from stark.service.v1 import site
    from app01 import models
    from django.shortcuts import HttpResponse
    
    
    class DepartHandler(object):
        def __init__(self, model_class):
            self.model_class = model_class
    
        def changelist_view(self, request):
            """
            列表页面
            :param request:
            :return:
            """
            return HttpResponse("部门列表页面")
    
        def add_view(self, request):
            """
            添加页面
            :param request:
            :return:
            """
            pass
    
        def change_view(self,request, pk):
            """
            编辑页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
        def delete_view(self, request, pk):
            """
            删除页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
    
    class UserInfoHandler(object):
        def __init__(self, model_class):
            self.model_class = model_class
    
        def changelist_view(self, request):
            """
            列表页面
            :param request:
            :return:
            """
            return HttpResponse("用户列表页面")
    
        def add_view(self, request):
            """
            添加页面
            :param request:
            :return:
            """
            pass
    
        def change_view(self,request, pk):
            """
            编辑页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
        def delete_view(self, request, pk):
            """
            删除页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
    
    site.register(models.Depart, DepartHandler)
    site.register(models.UserInfo, UserInfoHandler)

    app02/stark.py

    from stark.service.v1 import site
    from app02 import models
    from django.shortcuts import HttpResponse
    
    
    class HostHandler(object):
        def __init__(self, model_class):
            self.model_class = model_class
    
        def changelist_view(self, request):
            """
            列表页面
            :param request:
            :return:
            """
            return HttpResponse("主机列表页面")
    
        def add_view(self, request):
            """
            添加页面
            :param request:
            :return:
            """
            pass
    
        def change_view(self,request, pk):
            """
            编辑页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
        def delete_view(self, request, pk):
            """
            删除页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
    
    site.register(models.Host, HostHandler)

    luffy_stark/urls.py

    from django.contrib import admin
    from django.urls import path, re_path
    from stark.service.v1 import site
    
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'^stark/', site.urls),
    ]

    将数据库迁移好后,启动django项目(在修改配置中加入--noreload),浏览器输入路由查看

     

     

     此时,已经能够自动生成URL了,我们再新建一个model类看一下,在app02下的models.py中新建一个Role类

    app02/models.py

    from django.db import models
    
    
    class Role(models.Model):
        """角色"""
        title = models.CharField(
            verbose_name="角色名称",
            max_length=32,
        )

    app02/stark.py

    from stark.service.v1 import site
    from app02 import models
    from django.shortcuts import HttpResponse
    
    
    class RoleHandler(object):
        def __init__(self, model_class):
            self.model_class = model_class
    
        def changelist_view(self, request):
            """
            列表页面
            :param request:
            :return:
            """
            return HttpResponse("角色列表页面")
    
        def add_view(self, request):
            """
            添加页面
            :param request:
            :return:
            """
            pass
    
        def change_view(self,request, pk):
            """
            编辑页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
        def delete_view(self, request, pk):
            """
            删除页面
            :param request:
            :param pk:
            :return:
            """
            pass
    
    
    site.register(models.Role, RoleHandler)

    做数据库迁移,python manage.py makemigrations/python manage.py migrate,然后重新启动django项目,查看是否为Role数据表类自动创建了URL

     

     程序运行逻辑:在django项目启动后,路由加载前,会执行app01和app02目录下的stark.py文件,而这两个stark.py文件都各自定义了models.py中数据表类所对应的视图函数,然后利用单例模式,调用了v1.py中实例化的site,并调用了site.register方法,该方法往实例变量self._registry(空列表)中添加元素,且该元素为字典格式,字典里自定义了两个键,第一个键为model_class,值为models.py中的数据表类,第二个键为handler_class,值为一个类,该类的方法为视图函数,需传入一个参数,参数为models.py中的数据表类,传入该参后方便对数据表进行增删改查等操作;总路由加载时,也调用了v1.py中实例化的site,并调用了site.urls静态方法,该方法返回值与include一样,但返回的第一个元素为调用自身的self.get_urls()方法,get_urls方法定义了一个patterns空列表,然后循环实例变量self._registry,每循环一次就往patterns列表中添加四个值,这四个值就是每张数据表所对应的url,每个url都对应了不同的视图函数

  • 相关阅读:
    list转datatable,SqlBulkCopy将DataTable中的数据批量插入数据库
    Html.BeginForm 与Section、Partial View 和 Child Action
    e.stopPropagation();与 e.preventDefault();
    NPOI导出
    Excel导入导出(篇二)
    Excel导入导出,通过datatable转存(篇一)
    ajax请求加载Loading或错误提示
    jQuery UI dialog
    Zebra_Dialog 弹出层插件
    Google浏览器导出书签
  • 原文地址:https://www.cnblogs.com/xuewei95/p/15921385.html
Copyright © 2020-2023  润新知