django的url分发封装
h2,
body>h3,
body>h4,
body>h1{
padding: 10px;
background-color: #4cae4c;
text-align: center;
}
body>h3,
body>h4{
width: 50%;
}
-->
url的分发与封装基础版
组件和应用App的区别,组件其不仅服务于当前项目,其还可以服务于其他项目,即可以重复使用,
路由分发的格式,路由器分发path()中第二个参数可以是视图方法,也可以是路由分发,传一个元祖,第一个数据是路径匹配用[]括起来路径,第二,第三个是None,path里面还可以嵌套,即可以分发若干路径
urlpatterns = [
path('admin/', admin.site.urls),
re_path('ad/',([
path('test/',test),
path('test2/',test), ],None,None)),
对url的分发进行封装
相关概念理解
第一首先得理解app注册的含义是什么
'Xadmin.apps.XadminConfig',
其注册含义就是执行app应用下面app.py文件下面的方法,当django启动的时候就开始执行方法以及函数,此外还有一个函数
from django.utils.module_loading import autodiscover_modules
class XadminConfig(AppConfig):
name = 'Xadmin'
def ready(self):
autodiscover_modules('Xadmin') #在App里面一定会执行的函数,扫描当前项目所有app,并执行括号里面的py文件
因此当某个项目像用到组件功能时,就引入该组件即可,所以把想要执行或者加载模块,就放在组件中 ,即Xadmin中的apps文件下,注意注册顺序
第二步函数设定与self的理解,切记,self指的是调用该类的对象
路由分发
第三步路径是django启动的时候就已经生成了,path()中的第二个参数必须是一个变量名
在A类中形成这样的路径
re_path('app01/blog',ModelXadmin(Blog,site).url)
re_path('app01/article',ModelXadmin(Article,site).url)
然后在B类中再次计算路径分发
假如是ModelXadmin(Article,site).url调用url,那么在B类中的self指的就是此时实例化的对象,self.model=Aritcle===app01.models.Article,因此可以做相应的增删改查
re_path('app01/article',[
re_path('app01/article/delete/(\d+)',self.test)..... re_path('app01/blog/delete/(\d+)'.self.test1)..... re_path('app02/A/delete/(\d+)',self.test)....
],None,None) 此时的self指的就是传进来的表名对应 的实例化对象
路由分发步骤
第一步在组件app中声明django启动时,就执行Xadmin相关的方法和模块
from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules class XadminConfig(AppConfig):
name = 'Xadmin'
def ready(self):
autodiscover_modules('XXadmin')
第二步在Xadmin中设计相关函数
#!/usr/bin/env python
# -*- coding:utf- -*-
from django.urls import path,re_path,include
from django.shortcuts import HttpResponse,render class ModelXadmin(object):
def __init__(self,model,site):
self.model=model
self.site=site
@property
def url(self): # self指调用他的对象,也就是site调用
url = []
url.append(re_path('^add/$',self.test))
url.append(re_path('^delete/(\d+)',self.test))
url.append(re_path('^update/(\d+)',self.test))
url.append(re_path('^check/(\d+)',self.test))
url.append(re_path('^\w+/$',self.test))
return url,None,None # [re_path('^delete/(\d+)',test),],None,None def test(self, request, *args):
print(self.model)
data_list=self.model.objects.all()
print(data_list)
return render(request, "XXadmin/XXadmin_check.html",{"data_list":data_list})
class XadminSite(object):
def __init__(self):
self._registry={} def get_url(self): # 对所有的表生成相应的路径 这是url调用的,因此此时的self就和url中self是一样的
url = []
for model, wait_class in self._registry.items(): # Xadmin.site.register(Blog)--->self._registry[model]=admin_class(model,self) ={blog:ModelXadmin(blog,site)}
app_name = model._meta.app_label
table_name = model._meta.model_name
url_base = re_path('^{0}/{1}/'.format(app_name,table_name),wait_class.url()) # 假如是blog注册 re_path('app01/blog',ModelXadmin(Blog,site))
# 用配置类分发路径,这样我就可以拿到配置类内的所有方法,包括 re_path('app01/article',ModelXadmin(Article,site)) url.append(url_base)
return url # [app01/article/,[re_path('^delete/(\d+)',test),],None,None] @property # 把该函数当成静态属性,可以通过 对象.urls调用,也就是在路由分发的时候这个函数就已经执行了
def urls(self):
return self.get_url(), None, None # [app01/article/,[re_path('^delete/(\d+)',test),],None,None],None,None
# 这个self是site调用这个方法,因此这个self指的是site,谁调用方法,方法里面的self就是该对象 def register(self,model,admin_class=None,**option):
if not admin_class:
admin_class=ModelXadmin
self._registry[model]=admin_class(model,self) # z注意这里需要传值,即把需要的值放在init里面, model指的注册时传进来的表名 site=XadminSite()
# Xadmin.site.urls # app01/article/add/
# 那个对象调用方法 # 路径在django启动的时候就生成的,但是匹配却是一层一层往上找的
# 加入
第三步在url中调用方法,进行路径分发,注意路径匹配的第二个参数必须是一个变量名,而不是函数执行否则报错
path('Xadmin/', Xadmin.site.urls),
静态方法装饰器@property
@property修饰类内的方法就相当于声明我这个类方法可以通过取属性的方法即通过以下方法调用函数
class AdminSite(object):
def __init__(self)
self._registry={} # 这里用下划线是为了区分函数和变量名 @property # 对所有的表生成相应的路径 这是url调用的,因此此时的self就和url中self是一样的
def urls(self):
return self.get_url(), None, None site=XadminSite()
site.urls # 这样就可以调用函数了 site.urls ="name" # 可以通过等号传参数
正是因为这样就会出现,函数名与__init__里面同名时self.urls=name,左边的代码就相当于执行了函数,这就会报以下错误,或者外边调用site.urls时,不知调用谁.因此registry函数封装的数据用_registry进行命名.
AttributeError: can’t set attribute ,
再以学生的成绩为例,
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < or score > :
raise ValueError('invalid score')
self.__score = score s = Student('Bob', )
s.score =
print (s.score)
结果是 s.score =
结果是
ValueError: invalid score
当只有@property修饰函数时,函数只可读,不可以修改,如果想要修改,则需要通过用setter再次定义函数,两者相结合可以有效判断输入的数据是否合法.但也要注意,命名避免重复,否则会出现无限调用函数,即递归情形.变量名不合法
FBV实现思路
第一步把以表名都添加到列表当中,但是这种方法不知道,调用谁.
url路径分发进阶版
思路图如下
细节补充
以下主要参考 https://www.cnblogs.com/ParisGabriel/p/9302634.html
函数传参问题
函数的缺省参数:
语法:
def 函数名 (形参名1=默认实参1, 形参2=默认实参2)
语句块
说明:
缺省参数必须从右至左依次存在的,如果一个参数有缺省参数,
则右侧的所有参数都必须有缺省参数 缺省参数可以通过关键字形式传参
def dog(name="Lc",flog=True): pass
dog("娜娜",False) # 位置传参
dog(flog=False) # 关键字传参
其他参数类型,(了解即可)
位置形参:
语法:
def 函数名(形参1, 形参2.......)
语句块
元组形参:
语法:
def 函数名(*元组形参名):
语句块
作用:
收集多余的位置传参
命名关键字形参:
语法:
def 函数名(*, 命名关键字形参):
语句块
或
def 函数名(*args, 命名关键字形参):
语句块
(关键字形参 必须用关键字传参)
作用:
强制所有的参数都参数都必须用关键字传参或字典关键字传参
双星号字典传参:
语法:
def 函数名(**字典形参名):
语句块
作用:
收集多余关键字传参
字典形参名通常命名为:kwargs
函数的参数说明:
位置形参、星号元组形参、命名关键字形参、双星号字典形参可以混合使用
函数自左到右的顺序为:
.位置形参
.星号元组形参
.命名关键字形参
.双星号字典形参
_meta方法补充(类表方法)
Python有反射机制,Django也不例外,也有很好的反射机制,每个Django模型都有一个属性_meta,_meta也有属性和方法,这些属性和方法反射出了模型的一些特性,
在django中_meta方法,内置有很多方法,有以下方法
_meta的属性和方法 '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_field_cache',
'_field_name_cache', '_fields', '_fill_fields_cache', '_fill_m2m_cache', '_fill_related_many_to_many_cache',
'_fill_related_objects_cache', '_join_cache', '_m2m_cache', '_many_to_many', '_name_map', '_prepare',
'_related_many_to_many_cache', '_related_objects_cache', '_related_objects_proxy_cache',
'abstract', 'abstract_managers', 'add_field', 'add_virtual_field', 'admin', 'app_label',
'auto_created', 'auto_field', 'concrete_managers', 'concrete_model', 'contribute_to_class',
'db_table', 'db_tablespace', 'duplicate_targets', 'fields', 'get_add_permission', 'get_all_field_names',
'get_all_related_m2m_objects_with_model', 'get_all_related_many_to_many_objects', 'get_all_related_objects',
'get_all_related_objects_with_model', 'get_ancestor_link', 'get_base_chain', 'get_change_permission',
'get_delete_permission', 'get_field', 'get_field_by_name', 'get_fields_with_model', 'get_latest_by',
'get_m2m_with_model', 'get_ordered_objects', 'get_parent_list', 'has_auto_field', 'init_name_map',
'installed', 'local_fields', 'local_many_to_many', 'managed', 'many_to_many', 'module_name', 'object_name',
'order_with_respect_to', 'ordering', 'parents', 'permissions', 'pk', 'pk_index', 'proxy', 'proxy_for_model',
'related_fkey_lookups', 'setup_pk', 'setup_proxy', 'unique_together', 'verbose_name', 'verbose_name_plural',
'verbose_name_raw', 'virtual_fields'
1 User._meta.get_field
(field_name),field是字符串,即可以通过字符串查到表对应字段对象,包括外键,但是要通过related_name进行查找.
注意 如果没有找到具有给定名称的字段, FieldDoesNotExist
则会引发异常
>>> from django.contrib.auth.models import User # A field on the model
>>> User._meta.get_field('username')
<django.db.models.fields.CharField: username> # A field from another model that has a relation with the current model
>>> User._meta.get_field('logentry')
<ManyToOneRel: admin.logentry> # A non existent field
>>> User._meta.get_field('does_not_exist')
Traceback (most recent call last):
...
FieldDoesNotExist: User has no field named 'does_not_exist'
得到某个字段对象后,就可以拿到相关的参数,如拿到字段 中文名,在页面布局的时候会用到
self.model._meta.get_field(field).verbose_name # verbose_name在admin中会用到
2 检索模型当中所有字段User._meta.get_fields()
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<ManyToOneRel: admin.logentry>,
<django.db.models.fields.AutoField: id>,
<django.db.models.fields.CharField: password>,
<django.db.models.fields.DateTimeField: last_login>,
<django.db.models.fields.BooleanField: is_superuser>,
<django.db.models.fields.CharField: username>,
<django.db.models.fields.CharField: first_name>,
<django.db.models.fields.CharField: last_name>,
<django.db.models.fields.EmailField: email>,
<django.db.models.fields.BooleanField: is_staff>,
<django.db.models.fields.BooleanField: is_active>,
<django.db.models.fields.DateTimeField: date_joined>,
<django.db.models.fields.related.ManyToManyField: groups>,
<django.db.models.fields.related.ManyToManyField: user_permissions>)
3 常用的方法
cls_name = model._meta.model_name #当前表映射类名称的小写
cls_name = modle._meta.object_name: #属性,模型名,字符串,返回自定义的类名原型.
app_name = model._class._meta.app_label #当前表所在app的名称 model._meta.auto_field: 属性,返回所有自增字段类型的字段,一般是`id`字段,如<django.db.models.fields.AutoField: id> db_table:属性,该模型所用的数据表的名称,关于数据表的名称
4
django的url分发封装的更多相关文章
- xadmin系列之django的url分发的方式
一.先介绍一下我们自己的urls中是如何进行路由分发的 一.一级路由 urlpatterns = [ url(r'^upload/', views.upload,name="upload&q ...
- Django学习之十一:真正理解Django的路由分发和反解url原理
目录 URL Dispatcher 简介 模式概念 对比URLPattern 与 URLResolver (多态的体现) 构建子路由几种方式 反解url算法逻辑 URL Dispatcher 简介 d ...
- django url分发,视图,模板回顾
Django基础轮廓 MTV+controller 一 url分发系统: 1 简单使用 url(r'^articles/2003/$', views.special_case_2003), # spe ...
- Django url分发到工程里
因为我们建立了Django后 ,url是在mysite下的全局对象 因为我们实际项目里不可能只有一个工程 而全放在全局里去分发url 会让代码耦合度提高,代码量大后会造成维护困难.这时候我们把url分 ...
- Django路由配置之子路由include(URL分发)
子路由include(URL分发) 在一个项目中可能存在多个应用,为了方便区分和管理,在项目的总路由urls.py中会进行路由分发: (1)项目总路由导入from django.conf.urls ...
- day53:django:URL别名/反向解析&URL分发&命名空间&ORM多表操作修改/查询
目录 1.URL别名&反向解析 2.URL分发&命名空间 3.ORM多表操作-修改 4.ORM多表操作-查询 4.1 基于对象的跨表查询 4.2 基于双下划线的跨表查询 4.3 聚合查 ...
- Django开发:(1)django基础 & url控制器
HTTP请求协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本 ...
- Django的URL调度
1.URLconf (URL configuration):(Django版本1.11.20,其它版本可能各有差异.) 在Django中Python后端与前端URL进行交互,是通过一个名为urlcon ...
- Django的URL路由系统
一. URL配置 URL配置就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图之间的映射表.你就是以这种方式告诉Django,对于哪个URL调用的这段代码. 基本格式 from ...
随机推荐
- POJ 1390 Blocks (区间DP) 题解
题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分. 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在 ...
- html/css中相对定位relative和绝对定位absolute的用法
一.相对定位(position:relative) 1.相对定位:将盒子的position属性设置为relative:可通过left.top.right.bottom设置偏移量. 相对定位基础用法示例 ...
- LaTeX 自动避免重复内容
在编辑自动化文档时,很容易出现在文档多处提及相同内容的情况.例如,描述某具体设备的图片,在多个工艺中都会用到,而又无法确定工艺出现顺序,或者对于不同企业,工艺不尽相同.这时我们可能会希望,latex帮 ...
- 渗透之路基础 -- 服务端请求伪造SSRF
简介:SSRF 服务器端请求伪造,有的大型网站在web应用上提供了从其他服务器获取数据的功能.使用户指定的URL web应用获取图片,下载文件,读取文件内容.通常用于控制web进而探测内网服务以及攻击 ...
- 互联网寒冬之泪:Android开发程序员,你够优秀吗?
我想每个开发者在学习成长的过程中,在面临技术难题的时候,都有经历过自我怀疑的过程,但是有时候这并不是你的错,大家都经历过如此的过程.我们作为一个开发者,在成长的过程中,总有一些小的胜利和小的沮丧,学着 ...
- Flask学习之旅--还是数据库(sqlacodegen + SQL Alchemy)
一.写在前面 其实之前已经写过一篇关于 Flask 中使用数据库的博客了,不过那一篇博客主要是记录我在使用 Flask + MySQL8.0 时所遇到的一些问题(如果用的不是 MySQL8.0估计就没 ...
- HTML定位和布局----float浮动
1.定位体系一共有三种 (1)常规流: (2)浮动定位 (3)绝对定位 2.float属性常用的语法: (1)float:left:左浮动 (2)float:right:右浮动 (3)float:no ...
- js-数据交互--AJAX
一:介绍 今天跟下大家简单的介绍一下,在前端开发中,前后端数据交互的一种手段,我们都知道,在前端往后端传送数据的话,利用get,post方法即可向后端发送数据,后端将数据接受,链接到数据库,进行数据库 ...
- PTA A1014
A1014 Waiting in Line (30 分) 题目内容 Suppose a bank has N windows open for service. There is a yellow l ...
- SqlServer Left、Right、CharIndex函数
LEFT 函数:返回字符串中从左边开始指定个数字符 RIGT.H 函数:返回字符串从右边开始指定个数字符 len函数:LEN 函数返回文本字段中值的长度. CHARINDEX函数:CHARINDEX ...