2024--Django平台开发-Django知识点(四)

1.知识回顾

  • 创建项目:新项目、别人项目、新版版、老版本 + 项目目录(v1.0版本)

  • 路由系统

    • 常见路由编写加粗样式

      /index/             函数
      /index/<str:v1>     函数
      re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy),
      re_path(r'yy/(?P<v1>\d{4})-(?P<v2>\d{2})-(?P<v3>\d{2})/', views.mm),
      
      def yy(request,a1,a2,aa3):
      	pass
      	
      def mm(request,v1,v2,v3):
      	pass
      
    • 路由的命名

      /index/             函数        name='xx1'
      /index/<str:v1>     函数        name='xx2'
      

      注意:权限的校验。

    • 路由底层的实现

      • 路由定义的本质

        python 复制代码
        urlpatterns = [
            # URLPattern.resolve   -> RoutePattern.match
            URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
        
            # resolve -> RoutePattern.match
            path('login/', views.login),  # resolve
            re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy),
        ]
      • 输入网址访问我们的网站:

        • 原生请求 -> 封装Request对象 /info/v1/

        • ...

        • URLResolver.resolve

          resolver = URLResolver("/")
          resolver.resolve
          	for pattern in self.url_patterns:
          		pattern=URLPattern对象.resolve
          		URLPattern对象.RoutePattern对象.match   /info/v1/
          

答疑:path / re_path 有啥区别呀?

  • 表象:

    • path

      python 复制代码
      path('login/', views.login)
      path('other/<int:v1>/<str:v2>/', views.other)
    • re_path

      python 复制代码
      re_path(r'yy/(\d{4})-(\d{2})-(\d{2})/', views.yy)
  • 底层

    path = partial(_path, Pattern=RoutePattern)
    re_path = partial(_path, Pattern=RegexPattern)
    
    • path

      python 复制代码
      path('login/', views.login)
      path('other/<int:v1>/<str:v2>/', views.other)
      
      URLPattern(RoutePattern("login/", name=None, is_endpoint=True), views.login, None, None),
    • re_path

      python 复制代码
      re_path(r'yy/(\d{4})/', views.yy)
      
      URLPattern(RegexPattern("yy/(\d{4})/", name=None, is_endpoint=True), views.yy, None, None),

2.路由系统

2.1 常见路由

...

2.2 路由名称

...

2.3 路由底层实现

...

2.4 路由分发

研究django admin源码时:

namespace是什么?

  • 无namespace

    python 复制代码
    from django.urls import reverse
    
    url = reverse("v2")
    print(url)
  • 有namespace

    python 复制代码
    from django.urls import reverse
    
    url = reverse("namespace名称:v2")
    print(url)
    
    url = reverse("namespace名称:namespace名称:v2")
    print(url)

问题:什么叫反向生成?

path('login/login/login/login/', views.login, name='login'),

2.5 路由本质

2.5.1 关于导入和反射

  • 反射,以字符串的形式去操作对象中的成员。
  • 导入模块

2.5.2 include源码

python 复制代码
urlpatterns = [
    path('login/', views.login),
    path('api/', include("apps.base.urls")),
    path('api/', (
        import_module("apps.base.urls"),              # 模块对象 from app.base import urls
        None, 
        None)
    )
]
python 复制代码
urlpatterns = [
    path('login/', views.login),
    
    path('api/', include("apps.base.urls")),
    path('api/', (
        import_module("apps.base.urls"),              # 模块对象 from app.base import urls
        None, 
        None)
    ),
    
    path('web/', (
        [
        	path('v1/', www_views.login, name='v1'),
        	path('v2/', www_views.login, name='v2'),
		], 
        None, 
        None)
	),
]

在path执行时,传入的参数种类:

  • 网址 + 函数

  • 网址 + (模块对象,None,None)

    urlpatterns = [
    	...
    ]
    
  • 网址 + (列表,None,None)

2.5.3 path源码

  • 网址 + 函数

    python 复制代码
    path('login/', views.login),
    
    URLPattern(
        RoutePattern("login/", name=None, is_endpoint=True), 
        views.login, 
        None, 
        None
    )
  • 网址 + (模块对象,None,None)

    python 复制代码
    path('api/', include("apps.base.urls")),
    path('api/', (
        import_module("apps.base.urls"),              # 模块对象 from app.base import urls
        None, 
        None)
    ),
    
    URLResolver(
        RoutePattern('api/',name=None,is_endpoint=False),
        import_module("apps.base.urls"),              # 模块对象 from app.base import urls
        None,
        app_name=None,
        namespace=None
    )
  • 网址 + (列表,None,None)

    python 复制代码
    path('web/', (
        [
            path('v1/', www_views.login, name='v1'),
            path('v2/', www_views.login, name='v2'),
        ], 
        None, 
        None)
    )
    
    URLResolver(
        RoutePattern('api/',name=None,is_endpoint=False),
    	[
            path('v1/', www_views.login, name='v1'),
            path('v2/', www_views.login, name='v2'),
        ], 
        None,
        app_name=None,
        namespace=None
    )

所有URL用类和对象嵌套的形式实现:

python 复制代码
from django.urls import path, re_path, include
from apps.www import views

from django.urls import URLPattern, ResolverMatch
from django.urls.resolvers import RoutePattern
from importlib import import_module
from apps.www import views as www_views
from django.urls.resolvers import URLResolver

urlpatterns = [
    URLPattern(
        RoutePattern("login/", name=None, is_endpoint=True),
        views.login,
        None,
        None
    ),
    URLResolver(
        RoutePattern('api/', name=None, is_endpoint=False),
        import_module("apps.base.urls"),  # 模块对象 from app.base import urls
        None,
        app_name=None,
        namespace=None
    ),
    URLResolver(
        RoutePattern('web/', name=None, is_endpoint=False),
        [
            path('v1/', www_views.login, name='v1'),
            path('v2/', www_views.login, name='v2'),
        ],
        None,
        app_name=None,
        namespace=None
    )
]

2.5.4 路由匹配源码

1.请求来了
2.路由匹配


3.匹配过程

答疑:多个app的时候,路由分发到不同的app里,如果1个app,有100个路由,能不能按大类功能进行分组。

path('api/user/login/', views.login, name='login'),
path('api/user/logout/', views.login, name='login'),
path('api/user/order/', views.login, name='login'),
path('api/user/info/', views.login, name='login'),
path('api/user/ad/', views.login, name='login'),

2.6 关于网址之后的 /

  • APPEND_SLASH = True

    path('login/', views.login, name='login')
    	http://127.0.0.1:8000/login/  成功
    	
    	http://127.0.0.1:8000/login   重定向,GET
    	http://127.0.0.1:8000/login/   
    

    当我们直接访问网址或GET请求访问网址,都会成功,如果是POST请求有问题。

  • APPEND_SLASH = False

    path('login/', views.login, name='login')
    	http://127.0.0.1:8000/login/   成功
    	http://127.0.0.1:8000/login    失败
    	
    path('login', views.login, name='login')
    	http://127.0.0.1:8000/login/   失败
    	http://127.0.0.1:8000/login    成功
    

    严格模式,自己定义是什么就以什么方式访问。

2.7 其他

3.视图

3.1 FBV和CBV

问题:你习惯用函数视图比较多还是类视图比较多。

  • 非前后端分离,FBV
  • 前后端分离、小程序API,CBV【django rest framekwork框架)

3.2 参数

  • request对象,读取请求相关所有的数据。

    request.method
    request.GET        ?name=123&age=123&age=199   =>  特殊的字典:{name:[123],"age":[123,1999]}
    reqeust.POST
    request.FILES
    request.path_info
    request.body
    
    request.resover_math
    request.session
    
  • v1,v2 或 *args,**kwargs,用于接收动态路由中的参数值

3.3 业务处理

...

3.4 返回值

python 复制代码
from django.http import HttpResponse
from django.http import JsonResponse
from django.shortcuts import render, redirect

# `构建` 响应体和响应头
# return HttpResponse("中国北京")
# return JsonResponse({"status": True, "name": "一夜白头"}, json_dumps_params={"ensure_ascii": False})
# return render(request, "demo.txt")
# return redirect("https://www.baidu.com") # 301/302

问题:那什么时候是301,什么时候是302?

python 复制代码
class HttpResponseRedirect(HttpResponseRedirectBase):
    status_code = 302  # 临时重定向

class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
    status_code = 301  # 永久重定向
pythonav.com
5xclass.com 【运行】

4.HTML模板

希望数据 + 嵌套 HTML标签,返回给用户浏览器。

4.1 基本使用

  • 编写

    python 复制代码
    def demo(request):
    	# 业务处理,获取到值
    	user_list = ["一夜白头","星翼"]
    	
    	# 1.寻找demo.html,去哪里找? 优先DIRS,再去已注册APP的templates
    	# 2.读取文件内容 + 参数 => 模板渲染(替换)【模板语法】
    	# 3.封装到HttpResponse的请求体中
    	# 4.后续给用户返回
        return render(request,"demo.html",{"v1":user_list})
  • 寻找

    python 复制代码
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.staticfiles',
        "apps.app01.apps.App01Config",
        "apps.www.apps.WwwConfig",
    ]
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    # 'django.contrib.auth.context_processors.auth',
                    # 'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]

4.2 底层处理方式

python 复制代码
namespace = {'name': 'wupeiqi', 'data': [18, 73, 84]}
code = '''def hellocute():return  "name %s ,age %d" %(name,data[0],) '''
func = compile(code, '<string>', "exec")
exec(func, namespace)
result = namespace['hellocute']()
print(result)


info="""
def _execute():
    _buffer = []
    _buffer.append("<h1>")
    _buffer.append(name)
    _buffer.append("123")
    _buffer.append("</h1>")
    return "".join(_buffer)
"""
func = compile(info, '<string>', "exec")
exec(func, namespace)
result = namespace['_execute']()
print(result)

4.3 其他

1.继承

2.导入

3.常见问题和应用

  • 页面的title问题
  • 关于模板渲染的时机

4.4 自定义模板函数

  • app必须注册

  • 创建templatetags的文件夹

  • 任意创建文件,内容:

    python 复制代码
    from django.template.library import Library
    
    register = Library()
    
    
    @register.simple_tag()
    def my_func(v1, v2, v3):
        return "哈哈哈哈" + v1 + v2 + v3
    
    
    @register.inclusion_tag("xo.html")
    def my_xo(num):
        return {"x1": [item for item in num if item > 22]}
    
    
    @register.filter
    def my_tt(a1, a2):
        return "哈哈哈" + a1 + a2
  • 调用

    {% load xxx %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>{{ name }}</div>
    <div>{{ num }}</div>
    <div>{% my_func "一夜白头" "星翼" name %}</div>
    <div>{% my_xo num %}</div>
    <div>{{ "alex"|my_tt:"xxxx" }}</div>
    {% if "alex"|my_tt:"xxxx" %}
        <h1>真</h1>
    {% else %}
        <h1>家</h1>
    {% endif %}
    </body>
    </html>
    
  • 片段:xo.html

    <ul>
        {% for item in x1 %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    


相关推荐
Tttian6222 分钟前
基于Pycharm与数据库的新闻管理系统(2)Redis
数据库·redis·pycharm
做梦敲代码1 小时前
达梦数据库-读写分离集群部署
数据库·达梦数据库
小蜗牛慢慢爬行2 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger2 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
微服务 spring cloud2 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡2 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷2 小时前
Redis
数据库·redis·缓存
仰望大佬0073 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
学不透java不改名3 小时前
sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
数据库