python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件)

本文主要是介绍python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件)

一、内容回顾

类可否作为字典的key

初级

举例:

class Foo(object):pass_registry = {Foo:123
}print(_registry)
View Code

执行输出:

{<class '__main__.Foo'>: 123}

说明说法是成立的。

 

中级

class User(object):passclass Role(object):passclass Bar(object):def __init__(self,b):self.b = b_registry = {User:Bar(User),Role:Bar(Role),
}print(_registry)
View Code

执行输出:

{<class '__main__.Role'>: <__main__.Bar object at 0x00000158F1BFC668>, <class '__main__.User'>: <__main__.Bar object at 0x00000158F1B39320>}

 

高级

class User(object):passclass Role(object):passclass Bar(object):def __init__(self,b):self.b = b_registry = {User:Bar(User),Role:Bar(Role),
}for k,v in _registry.items():print(k, v.b)
View Code

执行输出:

<class '__main__.Role'> <class '__main__.Role'>
<class '__main__.User'> <class '__main__.User'>

从结果上来看,k和v.b 结果是一样的!请记住这个例子,下面的内容会用到!

 

通过model获取app名和类名

创建一个项目untitled,注意:django版本为1.11

进入命令行,创建第二个应用

python manage.py startapp app02

修改settings.py,注册2个app

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',
]
View Code

 

修改 app01-->models.py,新建表名为UserInfo

from django.db import models# Create your models here.
class UserInfo(models.Model):username = models.CharField(verbose_name="用户名",max_length=32)
View Code

 

修改 app02->models.py,新建表名为Role

from django.db import models# Create your models here.
class Role(models.Model):title = models.CharField(verbose_name="名称", max_length=32)
View Code

使用2个命令,生成表

python manage.py makemigrations
python manage.py migrate

 

修改urls.py,添加路由和视图

from django.conf.urls import url
from django.contrib import admin###视图暂时写在这里
from django.shortcuts import HttpResponse
from app01 import models as m1
from app02 import models as m2
def index(request):print(m1.UserInfo)print(m2.Role)return HttpResponse('ok')urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', index),
]
View Code

启动django项目,访问页面:

查看Pycharm控制台输出:

<class 'app01.models.UserInfo'>
<class 'app02.models.Role'>

 

获取app名和类名

修改urls.py

from django.conf.urls import url
from django.contrib import admin###视图暂时写在这里
from django.shortcuts import HttpResponse
from app01 import models as m1
from app02 import models as m2
def index(request):print(m1.UserInfo,m1.UserInfo._meta.app_label,m1.UserInfo._meta.model_name)print(m2.Role,m1.UserInfo._meta.app_label,m1.UserInfo._meta.model_name)return HttpResponse('ok')urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^index/', index),
]
View Code

刷新页面,查看Pycharm控制台输出:

<class 'app01.models.UserInfo'> app01 userinfo
<class 'app02.models.Role'> app01 userinfo

可以发现,app名和表名,都出来了!

 

二、单例模式

举例1

新建文件a.py

class AdminSite(object):passobj1 = AdminSite()
obj2 = AdminSite()# id表示查看对象的内存地址
print(obj1,id(obj1))
print(obj2,id(obj2))
View Code

执行输出:

<__main__.AdminSite object at 0x000001A3175549E8> 1799982762472
<__main__.AdminSite object at 0x000001A3175549B0> 1799982762416

可以看出内存地址不一样,它不是单例模式!

 

举例2

修改a.py

class AdminSite(object):passobj1 = AdminSite()
obj2 = AdminSite()
View Code

 

创建c.py

import aprint(a.obj1,id(a.obj1))
View Code

 

创建b.py

import aprint(a.obj1,id(a.obj1))import c
View Code

导入模块关系如下:

c导入了a,b导入了a,同时也导入到c。

那么a会重复导入吗?

 

执行b.py,输出:

<a.AdminSite object at 0x0000024FA2354E80> 2541047074432
<a.AdminSite object at 0x0000024FA2354E80> 2541047074432

内存地址一致,说明a没有重复导入,这个就是一个最简单的单例模式!

那么以后使用单例模式时,先声明一个类,再实例化。其它模块导入使用时,直接引用变量。

这样,就可以形成一个单例模式,节省内存!

 

举例3

修改a.py

class AdminSite(object):def __init__(self):self._registry = {}obj1 = AdminSite()
View Code

 

修改b.py

import aa.obj1._registry['k1'] = 11import cprint(a.obj1._registry)
View Code

 

 

修改c.py

import aa.obj1._registry['k2'] = 22
View Code

 

执行b.py,输出:

{'k2': 22, 'k1': 11}

其它调用者,就可以操作同一个字典。如果key重名,那么后执行,覆盖前端的!

 

三、路由系统

include

修改untitled项目的urls.py,增加路由

from django.conf.urls import url,include
from django.contrib import adminurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', include('app01.urls')),
]
View Code

 

在app01目录下创建文件urls.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^login/', views.login),url(r'^logout/', views.logout),
]
View Code

 

修改app01-->views.py

from django.shortcuts import render,HttpResponse# Create your views here.
def login(request):return HttpResponse('login')def logout(request):return HttpResponse('logout')
View Code

访问登录页面:http://127.0.0.1:8000/rbac/login/

路由就相当于

url(r'^/rbac/login/', views.login),

 

再分发一层

修改app01-->urls.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^login/', views.login),url(r'^logout/', include('app01.urls2')),
]
View Code

 

修改app01-->urls2.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^x1/', views.x1),url(r'^x2/', views.x2),
]
View Code

 

修改app01-->views.py

from django.shortcuts import render,HttpResponse# Create your views here.
def login(request):return HttpResponse('login')def logout(request):return HttpResponse('logout')def x1(request):return HttpResponse('x1')def x2(request):return HttpResponse('x2')
View Code

 

访问url:http://127.0.0.1:8000/rbac/logout/x1/

那么路由就相当于这样

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^/rbac/login/', views.login),url(r'^/rbac/logout/x1/', views.login),url(r'^/rbac/logout/x2/', views.login),
]

 

name

name是为了做url反向解析的

修改app01-->urls.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^login/', views.login, name='login'),url(r'^logout/', include('app01.urls2')),
]
View Code

 

修改app01-->urls2.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^x1/', views.x1, name='x1'),url(r'^x2/', views.x2, name='x2'),
]
View Code

 

namespace

namespace是为防止url重名

修改 untitled-->urls.py,这个是总路由

from django.conf.urls import url,include
from django.contrib import adminurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', include('app01.urls',namespace='rbac')),
]
View Code

 

修改app01-->urls.py

from django.conf.urls import url,include
from app01 import viewsurlpatterns = [url(r'^login/', views.login, name='login'),url(r'^logout/', include('app01.urls2',namespace='logout')),
]
View Code

那么urls2.py里面的路由,使用反向解析时,就相当于

rbac:logout:x1
rbac:logout:x2

总结:

include可以随意分层,namespace反向解析时,必须带上命名空间。

 

假设django没有提供include,怎么办?

看include源码,它返回了3个值

return (urlconf_module, app_name, namespace)

注意:return返回多个值时,它是一个元组!

 

修改urls.py,修改rbac,它必须返回3个值。最后面的rbac是命名空间

url(r'^/rbac/', (None,None,'rbac')),

再修改,完整代码如下:

第一个值是最重要的,另外2个参数为None也无所谓

from django.conf.urls import url,include
from django.contrib import admin
from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', ([url(r'^login/', views.login, name='login'),url(r'^logout/', views.logout, name='logout'),],None,'rbac')),
]
View Code

重启django程序,访问页面:http://127.0.0.1:8000/rbac/login/

 

再分发一次,修改urls.py,要指定3个值

url(r'^rbac/', ([url(r'^login/', views.login, name='login'),url(r'^logout/', views.logout, name='logout'),url(r'^x1/', (None,None,None)),
],None,'rbac')),

进阶修改

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', ([url(r'^login/', views.login, name='login'),url(r'^logout/', views.logout, name='logout'),url(r'^x1/', ([url(r'^add/', views.add, name='add'),url(r'^change/', views.change, name='change'),],None,None)),],None,'rbac')),
]
View Code

修改 app01-->views.py

from django.shortcuts import render,HttpResponse
from django.urls import reverse# Create your views here.
def login(request):url1 = reverse('rbac:add')print(url1)return HttpResponse('login')def logout(request):return HttpResponse('logout')def x1(request):return HttpResponse('x1')def x2(request):return HttpResponse('x2')def add(request):return HttpResponse('add')def change(request):return HttpResponse('change')
View Code

重启django程序,访问页面:http://127.0.0.1:8000/rbac/login/

查看Pycharm控制台输出:

/rbac/x1/add/

可以看到,能反向解析出url

 

修改urls.py,更改命名空间为xxx

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^rbac/', ([url(r'^login/', views.login, name='login'),url(r'^logout/', views.logout, name='logout'),url(r'^x1/', ([url(r'^add/', views.add, name='add'),url(r'^change/', views.change, name='change'),],None,'xxx')),],None,'rbac')),
]
View Code

修改 app01-->views.py,指定命名空间

重启django程序,访问页面:http://127.0.0.1:8000/rbac/login/

查看Pycharm控制台输出,效果同上

 

有些项目录音没有写在urls.py里面,那么在其它地方,肯定有操作urlpatterns变量的!

 

查看admin路由

创建超级用户

python manage.py createsuperuser

修改 app01-->admin.py,注册表

from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.UserInfo)
View Code

登录admin后台,点击表userinfo

查看的url为:

http://127.0.0.1:8000/admin/app01/userinfo/

点击添加,url为

http://127.0.0.1:8000/admin/app01/userinfo/add/

点击修改,url为

http://127.0.0.1:8000/admin/app01/userinfo/1/change/

点击删除,url为

http://127.0.0.1:8000/admin/app01/userinfo/1/delete/

注意:这些URL是自动添加的,执行这一行代码,就添加了4个URL

admin.site.register(models.UserInfo)

 

它是在路由加载之前操作的!

每一个应用,都有admin.py。它一定是在路由加载之前,就添加了路由!
否则上述几个页面是无法访问的。

那么它是如何做的呢?查看admin模块源码

def autodiscover():autodiscover_modules('admin', register_to=site)

它调用了autodiscover方法,它是用来做自动发现的。用来动态添加路由!

上面的'admin'指的是admin模块。它会自动寻找每一个应用名下的admin.py文件,并加载!

 

四、stark组件

stark组件介绍

stark组件是根据Django admin为原型写的一个组件,能够让我们告别增删改查.stark组件是可插拔试的组件,

移植性强,而且只用配置文件就能够得到想要的数据。

 

注意:这个不是django的组件。是自己根据admin为原型开发的!并没有统一的标准。

stark名字的由来

stark来源于《冰与火之歌》里面的史塔克。

史塔克家族是北境最古老也是最重要的家族,是北境各大小封臣的总领主,在被伊耿一世征服之前曾是独立数千年的北境之王。

名字叫啥都可以,看你的爱好了!貌似大家都会叫stark组件。

 

为什么要用stark组件

虽然django 提供的admin后台,能快速对一个表做增加改查。但是在生成环境中,是不会用admin后台的。

因为admin只是提供了简单的功能,在企业复杂环境中,需要自己定制功能。那么开发一套适合企业环境的stark组件,尤为重要!比如项目设计到几十张表的时候!

 

初始工作

创建应用stark并注册

在untitled项目的基础上,创建一个应用stark

这个应用,是专门做增删改查的!

python manage.py startapp stark

修改settings.py,注册app

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',
]
View Code

 

修改 stark-->apps.py

from django.apps import AppConfigclass StarkConfig(AppConfig):name = 'stark'def ready(self):# 导入自动发现模块from django.utils.module_loading import autodiscover_modules# 查找每一个应用下的stark模块,也就是stark.pyautodiscover_modules('stark')
View Code

注意:这里导入了自动发现模块,并指定模块为stark。那么它会读取settings.py里面注册的每一个应用。并查找应用下的stark.py文件是否存在。存在就加载,否则不加载!

 

在app01和app02目录下,分别创建stark.py

修改 app01-->stark.py,内容如下:

print(666)

重启django项目,查看Pycharm控制台输出:

666
666

它会执行2次,至于为什么会执行2次。这个就不知道了!

 

启动步骤

1. 读取配置文件,找到stark组件

2. 在路由匹配之前,会查找所有app名下的stark.py文件

3. 执行stark.py,在路由里面添加数据

 

注意:如果要应用stark组件,其他应用比如创建stark.py。并做相关配置,就可以使用stark组件了!

 

配置stark组件

在stark应用目录下,创建server目录,在此目录下新建文件stark.py

class AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'start'self.namespace = 'start'def register(self,model_class):# 添加键值对,固定值为1self._registry[model_class] = 1print(self._registry)  # 打印字典

site = AdminSite()  # 实例化类
View Code

修改 app01-->stark.py

# 这里的site,指的是实例化后的变量名
from stark.server.stark import site
from app01 import modelssite.register(models.UserInfo)  # 注册表
View Code

修改 app02-->stark.py

# 这里的site,指的是实例化后的变量名
from stark.server.stark import site
from app02 import modelssite.register(models.Role)  # 注册表
View Code

重启django项目,查看Pycharm控制台输出:

{<class 'app01.models.UserInfo'>: 1}
{<class 'app01.models.UserInfo'>: 1, <class 'app02.models.Role'>: 1}
{<class 'app01.models.UserInfo'>: 1}
{<class 'app02.models.Role'>: 1, <class 'app01.models.UserInfo'>: 1}

注意:如果输入内容为空!那是因为stark应用下的apps.py没有配置ready方法!!!

 

由于字典是无序的,所有显示的顺序和大家可能不一样。不要诧异!

从上面的输出,可以看出。现在字典有2个值,分别是

<class 'app02.models.Role'>: 1和<class 'app01.models.UserInfo'>: 1

 

这是一个单例模式,app01和app02共同操作了同一个字典_registry

 

修改  stark-->server-->stark.py

class StarkConfig(object):def __init__(self,model_class):self.b = model_classclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'start'self.namespace = 'start'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_classself._registry[model_class] = stark_config(model_class)# print(self._registry)  # 打印字典for k, v in self._registry.items():print(k, v.b)# print(id(k), id(v.b))

site = AdminSite()  # 实例化类
View Code

重启django项目,查看Pycharm控制台输出:

<class 'app01.models.UserInfo'> <class 'app01.models.UserInfo'>
<class 'app02.models.Role'> <class 'app02.models.Role'>
<class 'app01.models.UserInfo'> <class 'app01.models.UserInfo'>
<class 'app01.models.UserInfo'> <class 'app01.models.UserInfo'>
<class 'app02.models.Role'> <class 'app02.models.Role'>
<class 'app01.models.UserInfo'> <class 'app01.models.UserInfo'>

从上面的结果可以看出,k和v.b的值是一样的!

为什么k和v.b的值是一样的呢?请参考文章的开头《类可否作为字典的key》里面的高级用法!

需要注意的是,stark_config(model_class)等同于StarkConfig(model_class)

还是一个就是if not None问题

看一下app01是如何注册UserInfo表的

site.register(models.UserInfo)  # 注册表

它并没有传入参数stark_config。那么register方法,会调用stark_config的默认参数,也就是None

 

修改  stark-->server-->stark.py,把key改规范一点

class StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'start'self.namespace = 'start'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{models.UserInfo:StarkConfig(models.UserInfo)models.Role:StarkConfig(models.Role)}"""for k, v in self._registry.items():print(k,v.model_class)site = AdminSite()  # 实例化类
View Code

重启django项目,查看Pycharm控制台输出,效果同上!

 

修改 app02-->stark.py,注册表时,传一个参数

# 这里的site,指的是实例化后的变量名
# StarkConfig表示类
from stark.server.stark import site,StarkConfig
from app02 import modelsclass RoleConfig(StarkConfig):passsite.register(models.Role,RoleConfig)  # 注册表
View Code

修改 stark-->server-->stark.py,打印k和v

class StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'start'self.namespace = 'start'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""for k, v in self._registry.items():print(k,v)site = AdminSite()  # 实例化类
View Code

重启django项目,查看Pycharm控制台输出

<class 'app01.models.UserInfo'> <stark.server.stark.StarkConfig object at 0x000001DEF35A09B0>
<class 'app02.models.Role'> <app02.stark.RoleConfig object at 0x000001DEF35A0860>
<class 'app01.models.UserInfo'> <stark.server.stark.StarkConfig object at 0x000001DEF35A09B0>
<class 'app01.models.UserInfo'> <stark.server.stark.StarkConfig object at 0x000001FD23D209E8>
<class 'app01.models.UserInfo'> <stark.server.stark.StarkConfig object at 0x000001FD23D209E8>
<class 'app02.models.Role'> <app02.stark.RoleConfig object at 0x000001FD23D20898>

可以发现,现在_registry字典有2个值了。key和value是不一样的

{app01.models.UserInfo:StarkConfig(app01.models.UserInfo),app02.models.Role:RoleConfig(app02.models.Role)
}

UserInfo对应StarkConfig,Role对应RoleConfig。

为什么是这样的呢?请参数面向对象的继承,因为时间关系,没法一一细说。

注意:self指的是实例化对象。如果实例化了StarkConfig,那么self就是StarkConfig类!

 

下面是一个面向对象的小练习,如果能弄懂,那么上面的结果,也就明白了

""" 第一个列子
class StarkConfig(object):def __init__(self, model_class,site):self.model_class = model_classself.site = sitedef func(self):print(666)class RoleConfig(StarkConfig):def func(self):print(999)obj1 = StarkConfig(11,22)
obj1.func() # obj1是谁的对象?StarkConfigobj2 = RoleConfig(44,55)
obj2.func() # obj2是谁的对象?RoleConfig对象
"""""" 第二个列子
class StarkConfig(object):def __init__(self, model_class, site):self.model_class = model_classself.site = sitedef func(self):print(666)def run(self):self.func()class RoleConfig(StarkConfig):def func(self):print(999)obj1 = StarkConfig(11,22)
obj1.run() # 666obj2 = RoleConfig(44,55)
obj2.run() # 999# self到底是谁?self是谁就是哪个类中先开始超找
"""""" 第三个列子
class StarkConfig(object):def __init__(self, model_class, site):self.model_class = model_classself.site = sitedef func(self):print(self.site)def run(self):self.func()class RoleConfig(StarkConfig):def func(self):print(self.site)obj1 = StarkConfig(11,22)
obj1.run() # 22obj2 = RoleConfig(44,55)
obj2.run() # 55
"""
View Code

 

修改 stark-->server-->stark.py,增加urls方法

第一个值是列表,这样做的目的,是为路由分发。

class StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""for k, v in self._registry.items():print(k,v)@propertydef urls(self):# self.app_name和self.namespace值是一样的,都是starkreturn [],self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

 

修改untitled-->urls.py,这个是总路由。导入site

from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
from stark.server.stark import siteurlpatterns = [url(r'^admin/', admin.site.urls),# site.urls等同于[],'stark','stark'url(r'^stark/', site.urls),url(r'^rbac/', ([url(r'^login/', views.login, name='login'),url(r'^logout/', views.logout, name='logout'),url(r'^x1/', ([url(r'^add/', views.add, name='add'),url(r'^change/', views.change, name='change'),],None,'xxx')),],None,'rbac')),
]
View Code

 

修改 stark-->server-->stark.py,增加get_urls方法

class StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""for k, v in self._registry.items():print(k,v)def get_urls(self):urlpatterns = []return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(),self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

 

修改 stark-->server-->stark.py,增加视图函数x1,x2

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def x1(self, request):return HttpResponse('stark x1')def x2(self, request):return HttpResponse('stark x2')def get_urls(self):urlpatterns = []urlpatterns.append(url(r'^x1/',self.x1))urlpatterns.append(url(r'^x2/', self.x2))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(),self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

 

修改untitled-->urls.py,这个是总路由。删除多余的代码

from django.conf.urls import url,include
from django.contrib import admin
from app01 import views
from stark.server.stark import siteurlpatterns = [url(r'^admin/', admin.site.urls),# 导入stark组件的路由url(r'^stark/', site.urls),
]
View Code

重启django项目,访问url: http://127.0.0.1:8000/stark/x1/

 

还可以再做一次路由分发

修改 stark-->server-->stark.py,增加4个路径

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def x1(self, request):return HttpResponse('stark x1')def x2(self, request):return HttpResponse('stark x2')def get_urls(self):urlpatterns = []urlpatterns.append(url(r'^x1/',self.x1))urlpatterns.append(url(r'^x2/', self.x2))urlpatterns.append(url(r'^x3/', ([url(r'^add/', self.x1),url(r'^change/', self.x1),url(r'^del/', self.x1),url(r'^edit/', self.x1),],None,None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(),self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

重启django项目,访问url:  http://127.0.0.1:8000/stark/x3/add/

 

这样写太麻烦了,使用for循环

修改 stark-->server-->stark.py

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def x1(self, request):return HttpResponse('stark x1')def x2(self, request):return HttpResponse('stark x2')def get_urls(self):urlpatterns = []# urlpatterns.append(url(r'^x1/',self.x1))# urlpatterns.append(url(r'^x2/', self.x2))# urlpatterns.append(url(r'^x3/', ([#                                      url(r'^add/', self.x1),#                                      url(r'^change/', self.x1),#                                      url(r'^del/', self.x1),#                                      url(r'^edit/', self.x1),#                                  ],None,None)))for k, v in self._registry.items():# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象# k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象app_label = k._meta.app_labelmodel_name = k._meta.model_name# 为每一个表,添加增删改查的urlurlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), ([url(r'^add/', self.x1),url(r'^change/', self.x1),url(r'^del/', self.x1),url(r'^edit/', self.x1),],None,None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(),self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

重启django项目,访问userinfo表的添加方法

http://127.0.0.1:8000/stark/app01/userinfo/add/

效果如下:

 

但是urlpatterns固定了,这样不好

修改 stark-->server-->stark.py

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def x1(self, request):return HttpResponse('stark x1')def x2(self, request):return HttpResponse('stark x2')def get_urls(self):urlpatterns = [url(r'^list/$', self.x1),url(r'^add/$', self.x1),url(r'^(?P<pk>\d+)/change/', self.x1),url(r'^(?P<pk>\d+)/del/', self.x1),]return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(),self.app_name,self.namespacesite = AdminSite()  # 实例化类
View Code

 

视图函数的名字不够规范,需要改名

修改 stark-->server-->stark.py

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = siteclass AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def change_list(self, request):return HttpResponse('stark list')def change_add(self, request):return HttpResponse('stark add')def change_form(self, request, pk):return HttpResponse('stark form')def change_del(self, request, pk):return HttpResponse('stark del')def get_urls(self):urlpatterns = [url(r'^list/$', self.change_list),url(r'^add/$', self.change_add),url(r'^(?P<pk>\d+)/change/', self.change_form),url(r'^(?P<pk>\d+)/del/', self.change_del),]# for k, v in self._registry.items():#     # k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象#     # k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象#     app_label = k._meta.app_label#     model_name = k._meta.model_name#     urlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(), self.app_name, self.namespacesite = AdminSite()  # 实例化类
View Code

 

某一个表要增加方法呢?可以定义extra_url方法,用来扩展

修改 stark-->server-->stark.py

注意:这里要来一个大的变动。将AdminSite相关代码移植到StarkConfig,并在StarkConfig增加extra_url方法

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = sitedef change_list(self, request):return HttpResponse('stark list')def change_add(self, request):return HttpResponse('stark add')def change_form(self, request, pk):return HttpResponse('stark form')def change_del(self, request, pk):return HttpResponse('stark del')def get_urls(self):info = self.model_class._meta.app_label, self.model_class._meta.model_nameurlpatterns = [url(r'^list/$', self.change_list),url(r'^add/$', self.change_add),url(r'^(?P<pk>\d+)/change/', self.change_form),url(r'^(?P<pk>\d+)/del/', self.change_del),]extra = self.extra_url()if extra:  # 判断变量不为空# 扩展路由
            urlpatterns.extend(extra)return urlpatternsdef extra_url(self):  # 额外的路由,由调用者重构pass@propertydef urls(self):return self.get_urls()class AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def get_urls(self):urlpatterns = []for k, v in self._registry.items():# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象# k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象app_label = k._meta.app_labelmodel_name = k._meta.model_nameurlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(), self.app_name, self.namespacesite = AdminSite()  # 实例化类
View Code

 

修改 app02-->stark.py,重构extra_url方法。添加新的路由

# 这里的site,指的是实例化后的变量名
# StarkConfig表示类
from stark.server.stark import site,StarkConfig
from app02 import models
from django.conf.urls import url
from django.shortcuts import HttpResponseclass RoleConfig(StarkConfig):def sk2(self, request):return HttpResponse('sk2神仙水')def extra_url(self):data = [url(r'^sk2/$', self.sk2),]return datasite.register(models.Role,RoleConfig)  # 注册表
View Code

重启django项目,访问新增加的url:

http://127.0.0.1:8000/stark/app02/role/sk2/

效果如下:

那么role表,就有5个url了。

而userinfo表,只有4个url

 

查看admin相关源码,将url改成和admin的一致

修改 stark-->server-->stark.py

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = sitedef changelist_view(self, request):return HttpResponse('stark list')def add_view(self, request):return HttpResponse('stark add')def change_view(self, request, pk):return HttpResponse('stark change')def delete_view(self, request, pk):return HttpResponse('stark delete')def get_urls(self):info = self.model_class._meta.app_label, self.model_class._meta.model_nameurlpatterns = [url(r'^list/$', self.changelist_view),url(r'^add/$', self.add_view),url(r'^(?P<pk>\d+)/change/', self.change_view),url(r'^(?P<pk>\d+)/del/', self.delete_view),]extra = self.extra_url()if extra:  # 判断变量不为空# 扩展路由
            urlpatterns.extend(extra)return urlpatternsdef extra_url(self):  # 额外的路由,由调用者重构pass@propertydef urls(self):return self.get_urls()class AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def get_urls(self):urlpatterns = []for k, v in self._registry.items():# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象# k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象app_label = k._meta.app_labelmodel_name = k._meta.model_nameurlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(), self.app_name, self.namespacesite = AdminSite()  # 实例化类
View Code

 

增加别名

修改 stark-->server-->stark.py

from django.conf.urls import url
from django.shortcuts import HttpResponseclass StarkConfig(object):def __init__(self,model_class,site):self.model_class = model_classself.site = sitedef changelist_view(self, request):return HttpResponse('stark list')def add_view(self, request):return HttpResponse('stark add')def change_view(self, request, pk):return HttpResponse('stark change')def delete_view(self, request, pk):return HttpResponse('stark delete')def get_urls(self):info = self.model_class._meta.app_label, self.model_class._meta.model_nameurlpatterns = [url(r'^list/$', self.changelist_view, name='%s_%s_changelist' % info),url(r'^add/$', self.add_view, name='%s_%s_add' % info),url(r'^(?P<pk>\d+)/change/', self.change_view, name='%s_%s_change' % info),url(r'^(?P<pk>\d+)/del/', self.delete_view, name='%s_%s_del' % info),]extra = self.extra_url()if extra:  # 判断变量不为空# 扩展路由
            urlpatterns.extend(extra)return urlpatternsdef extra_url(self):  # 额外的路由,由调用者重构pass@propertydef urls(self):return self.get_urls()class AdminSite(object):def __init__(self):self._registry = {}self.app_name = 'stark'self.namespace = 'stark'def register(self,model_class,stark_config=None):# not None的结果为Tureif not stark_config:# 也就是说,当其他应用调用register时,如果不指定stark_config参数# 那么必然执行下面这段代码!# stark_config和StarkConfig是等值的!都能实例化stark_config = StarkConfig# 添加键值对,实例化类StarkConfig,传入参数model_class# self指的是AdminSite类self._registry[model_class] = stark_config(model_class,self)# print(self._registry)  # 打印字典"""{app01.models.UserInfo:StarkConfig(app01.models.UserInfo)app02.models.Role:RoleConfig(app02.models.Role)}"""# for k, v in self._registry.items():#     print(k,v)def get_urls(self):urlpatterns = []for k, v in self._registry.items():# k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象# k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象app_label = k._meta.app_labelmodel_name = k._meta.model_nameurlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))return urlpatterns@propertydef urls(self):# 调用get_urls方法# self.app_name和self.namespace值是一样的,都是starkreturn self.get_urls(), self.app_name, self.namespacesite = AdminSite()  # 实例化类
View Code

重启django项目,访问url: 

http://127.0.0.1:8000/stark/app02/role/list/

效果如下:

 

 

从django启动,到每一个表,生成了4个URL。这中间经历了复杂的过程!

 

流程图

 

说明:

注意以app01为例:

1. 启动时,执行settings.py。加载INSTALLED_APPS里面的app,从上到下执行!

 

2.执行到stark应用时,执行apps.py。执行ready方法,调用autodiscover_modules方法!
它会查找每一个app应用下的stark.py文件,并执行文件!

 

3. 执行stark.py时,执行from stark.server.stark import site。它会调用stark-->server-->stark.py里面的site
site执行了实例化

 

4. 再执行site.register(models.UserInfo)。它会调用stark-->server-->stark.py里面的register方法
执行self._registry[model_class] = stark_config(model_class,self),调用StarkConfig的__init__方法
self._registry增加key-value。value就是StarkConfig类

 

5.执行总路由,也就是urls.py,调用site.urls。这里的site就是stark-->server-->stark.py里面的site
执行AdminSite的urls方法。注意,它加了@property。所以可以site.urls执行方法。

 

6.它里面调用了get_urls方法,执行for循环,将url添加到urlpatterns列表中。以app01的userinfo表为列
url(r'^%s/%s/' % (app_label, model_name,)就相当于url(r'^app01/userinfo/',)
后面的(v.urls, None, None),它是一个元组。这就相当于执行了include。include它返回一个元组。必须有3个值
这里的v.urls,指的就是StarkConfig.urls。为什么v是StarkConfig类?看步骤4的key-value


7. 执行StarkConfig类的urls方法,注意:它加了@property,可以不需要括号,就可以执行。


8. 它调用了get_urls方法。这里的self就是StarkConfig类。执行get_urls方法里面的urlpatterns,它加了4个URL,用来做增删改查的。


9. 判断app应用下start.py是否重构了extra_url方法。如果是,执行自己应用下的extra_url方法。它必须返回一个列表。

    这里只有app02重构了extra_url方法。返回了一个列表。执行urlpatterns.extend(extra)。表示在urlpatterns列表中添加一个列表。


10. 此时在总路由中,urlpatterns数据结构如下:

urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^stark/', ([url(r'^app01/userinfo/', ([url(r'^list/$', self.changelist_view, name='app01_userinfo_changelist'),url(r'^add/$', self.add_view, name='app01_userinfo_add'),url(r'^(?P<pk>\d+)/change/', self.change_view, name='app01_userinfo_change'),url(r'^(?P<pk>\d+)/del/', self.delete_view, name='app01_userinfo_del'),],None,None)),],None,'stark')),
]

所以可以访问一下url: 

http://127.0.0.1:8000/stark/app01/userinfo/list/

效果如下:

 

完整代码,请访问github

https://github.com/987334176/luffy_stark/archive/v1.0.zip

posted @ 2018-08-28 21:29 肖祥 阅读( ...) 评论( ...) 编辑 收藏

这篇关于python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/490430

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听