• [Django框架1]基础知识概要


    Python调C 法力无边

    目前对于Python web来说,主流框架是Django和flask.有同学会问,什么是框架呢?打一个比方,就是这个包已经帮你做好了整体的框架(类似于骨架的概念),而你就是在里面缝缝补补,增加细节,一般也都是在settings.py上进行修改配置。
    当然了,Python 毕竟是脚本语言,性能上面远达不到我们所需要的要求,但是其用框架搭建网站是十分快捷的。对于学生来说或者一些小项目,可以考虑使用Python的上述两种框架。
    当然,对于前端的一些知识,可以在设计开发中慢慢增长,但是基础概念需要掌握的,不过不用在这里耗太久。
    而本次的Django框架也仅仅从模版模型表单视图等基本内容为主,后续再持续深入,特别是ORM数据库实例等,倘若还有时间再进行简单的管理系统进行开发。

    本次环境 Python 3.10 Pycharm 2022 Django 3.2

    简介与创建

    django本身基于mvc模型,即model view controller 设计模式。是快速开发网站、设计、部署网站的最佳组合。
    model:编写程序应有的功能,负责业务对象与数据库的映射
    view:图形界面,负责与用户的交互
    controller:负责转发请求,对请求进行处理

    使用pip 安装django:

    pip3 install Django -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    • 1

    或者直接在pycharm中下载对应的模块。

    使用命令行创建项目

    
    django-admin startproject helloworld
    cd helloworld/
    
    • 1
    • 2
    • 3

    或者使用pycharm进行创建(个人推荐使用命令行)
    在这里插入图片描述
    见helloworld文件包,可以看到如上的目录结构
    HelloWorld: 项目的容器。
    manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
    HelloWorld/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
    HelloWorld/asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
    HelloWorld/settings.py: 该 Django 项目的设置/配置。
    HelloWorld/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
    HelloWorld/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。

    如何运行了呢?使用如下命令,启动服务器,

    python3 manage.py runserver 127.0.0.1:8000
    
    • 1

    进入到如下界面,就说明已经配置成功了。(说真的,这个比配置tomcat和springboot简单多了,也不愧是快速开发的首选框架)
    请添加图片描述
    或者也可以在pycharm配置相应的设置方便快速。
    请添加图片描述
    由于创建的helloworld没有views.py文件,所以需要在此目录下创建views.py,并写相应的请求,这里以helloworld为例:

    from django.http import  HttpResponse
    
    def hello(request):
        return HttpResponse("Hello world!");
    
    • 1
    • 2
    • 3
    • 4

    同时需要在urls.py绑定views.hello,注意views.hello不要加括号

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import  url
    from . import  views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^$',views.hello),
        # path('hello/', views.hello),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Django path()可以接收4个参数,分别是两个必选参数:route 、view 和两个可选参数kwargs、name。
    route: 字符串,表示 URL 规则,与之匹配的 URL 会执行对应的第二个参数 view。
    view: 用于执行与正则表达式匹配的 URL 请求。
    kwargs: 视图使用的字典类型的参数。
    name: 用来反向获取 URL。

    Django模版

    上述内容中将数据与视图混合一起了,不符合MVC思想。而模版是一个文本,用于分离文档的表现形式和内容。
    在helloworld目录下创建Templates目录并建立runoob.html文件

    <h1>{{ hello world }}h1>
    
    • 1

    接下来在settings.py导入位置 ‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)],在这里插入图片描述
    修改 views.py,增加一个新的对象,用于向模板提交数据:
    其中render用来传递conText填充模版

    from django.shortcuts import  render
    
    def runoob(request):
        context = {}
        context['hello'] = 'hello world'
        return render(request,'runoob.html',context)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改urls.py:

    from django.urls import path
     
    from . import views
     
    urlpatterns = [
        path('runoob/', views.runoob),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    再次访问 http://127.0.0.1:8000/runoob即可访问了。

    Django模版标签

    变量
    模版语法:

    view: {"html-name" : "views-name"}
    HTML: { {变量名} }
    
    return render(request,"runoob.html",{"name":views_name})
    
    
    # runoob.html:
    <p>{ {name} } </p>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    列表

    在html中,可以用 . 索引下标取出对应的元素

    # views.py
    def runoob(request):
    	view_list = ["123","456"]
    	return render(request,"runoob.html",{"views_list":views_list})
    
    # 列表
    <p> {{view_list}}</p>
    <p> {{view_list.0}} </p>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    过滤器

    过滤器有lower. upper. truncatewords. addslashes. date length

    此处在runoob.html进行过滤
    {{变量名 | 过滤器:可选参数 }} 
    {{name|lower}}   # 模版过滤器可以在变量被显示前修改它,过滤器使用管道字符
    {{bio|truncatewords:"30"}} # 将显示bio的前三十个词
    
    • 1
    • 2
    • 3
    • 4

    过滤器的目的就是过滤使得获取到相应的字符内容
    下面讲一个safe:

    {{ views_str | safe}}
    标记为安全不需要转义,保障绝对安全才能用safe
    
    def runoob(request):
    	views_str = "点击跳转"
    	return render(request,"runoob.html",{"views_str":views_str})
    
    
    # runoob.html:
    {{ views_str |safe }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    标签

    if / else 标签:

    { % if condition %}
    	... display
    {% endif %}
    
    或者
    { % if condition1 %}
        ... display1
     {% elif condition2 %}
        ... display2
     {% else %}
    { % endif % }
    
    { % if  athlist and coachlist %}
    {% endif %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    for标签:
    { % for % }

    <ul>
    	{ % for athlete in athlete_list   (reversed)%}
    	     <li> {{ athlete.name }} </li>
    	{% endfor %}
    </ul>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    遍历字典:

    # views.py:
    def runoob(request):
    	views_dict={"name":"cai","age":18}
    	return render(request,"runoob.html",{"views_dict":views_dict})
    
    # runoob.html:
    { % for i ,j in views_dict.items %}
    {{i}} --- {{j}}
    {% endfor% }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ifequal/ifnotequal标签:
    { % ifequal %}比较两个值,当他们相等的时候,显示内容:

    {% ifequal user currentuser %}
       <h1> welcome </h1>
    {% else % }
    	<h1> No </h1>
    {% endifequal %}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注释

    { # 这是一个注释 #}
    
    • 1

    include 标签 允许在模版中包含其他的模版内容

    { % include "nav.html" % }
    
    • 1

    csrf_token
    用于form表单中,作用是跨站请求伪造保护。如果不用的话,再次跳转会抱403权限错误。

    自定义标签和过滤器

    在应用目录下,建一个templatetags (和templates同级)
    在该目录下建一个任意Py文件。

    # my_tag.py:
    from django import template
    
    register = template.Library() #register名字固定不可改变
    
    • 1
    • 2
    • 3
    • 4

    其中在settings.py templates下添加libraries配置:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [BASE_DIR, "/templates",],
            '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',
                ],
                "libraries":{                          # 添加这边三行配置
                    'my_tags':'templatetags.my_tags'   # 添加这边三行配置        
                }                                      # 添加这边三行配置
            },
        },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在my_tag.py中建立过滤器与自定义标签
    注意 {% 没有空格!!!

    @register.filter
    def my_filter(v1, v2):
        return v1 * v2
    
    @register.simple_tag
    def my_tag1(v1, v2, v3):
        return v1 * v2 * v3
    
    # 在html文件头部导入py文件
    {% load my_tag %}
    
    {{ 11|my_filter:22 }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    配置静态文件

    在根目录下创建statics目录,在settings最下方配置:

    STATIC_URL = '/static/' # 别名 
    STATICFILES_DIRS = [ 
        os.path.join(BASE_DIR, "statics"), 
    ]
    
    • 1
    • 2
    • 3
    • 4

    在statics目录下创建css目录 js目录 images目录 plugins目录 分别放css文件 js文件,图片,插件
    把bootstrap框架放入插件目录 plugins
    在html文件的head标签中引入bootstrap,注意引用路径的配置文件是别名static

    <link rel="stylesheet". href="/static/plugins/bootstrap-3.3.7/dist/css/bootstrap.css">
    # html:
    
    {% load static %}
    {{name}} <img src="{% static 'images/runoob-logo.png'%}" alt="runoob-logo">
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    模版继承

    用继承实现复用,减少冗余内容
    父模版 block … endblock 父模版中的预留区域

    {% block name %}
    预留给子模版的区域,可以设置默认内容
    {% endblock name %}
    
    • 1
    • 2
    • 3

    子模版 使用extends 继承父模版

    { % extends "父模版路径" %}
    
    • 1

    在templates目录下添加 base.html文件:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <p>菜鸟教程 Django 测试。</p>
        {% block mainbody %}
           <p>original</p>
        {% endblock %}
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使runoob.html对其继承

    {%extends "base.html" %}
     
    {% block mainbody %}
    <p>继承了 base.html 文件</p>
    {% endblock %}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Django 模型

    Django对数据库提供了很好的支持,提供了统一的调用API,先安装pymysql模块,本次使用的数据库为mysql,同时使用的是阿里云服务器主机ip.

    ORM

    ORM:对象关系映射,用于实现数据之间的转换。在业务逻辑层和数据库之间充当了桥梁的作用,通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。
    好处:提高了开发效率,不同数据库可以切换,但是需要转换sql语句时,执行效率低。
    其中 models:数据表 对象实例:一条记录 属性:字段

    *数据库配置

    在settings.py文件中找到databases配置项,将信息修改为:

    DATABASES = { 
        'default': 
        { 
            'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
            'NAME': 'runoob', # 数据库名称
            'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 ;有服务器就设置自己的服务器
            # 服务器记得关闭防火墙,嫌麻烦端口全部打开
            'PORT': 3306, # 端口 
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '123456', # 数据库密码
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在settings中的__init__.py中引入模块并进行配置:

    import pymysql
    pymysql.install_as_MySQLdb()
    
    • 1
    • 2

    定义模型

    使用命令创建app

    django-admin startapp TestModel
    
    • 1

    在TestModel/models.py文件夹下附以下代码:
    类名代表数据库表名,继承Model,字段(name),数据类型(CharField) maxlength参数限定长度

    from django.db import models
     
    class Test(models.Model):
        name = models.CharField(max_length=20)
    
    • 1
    • 2
    • 3
    • 4

    同时子啊settings.py中找到INSTALLED_APPS这一项,如下:

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'TestModel',               # 添加此项
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在命令行运行,当然也可以使用数据库工具,创建表TestModel_test

    use runoob
    create  table TestModel_test (
    	name varchar(20)
    )
    
    • 1
    • 2
    • 3
    • 4
    $ python3 manage.py migrate   # 创建表结构
    
    $ python3 manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
    $ python3 manage.py migrate TestModel   # 创建表结构
    
    • 1
    • 2
    • 3
    • 4

    *数据库操作

    在django框架中,统一都是继承Models,为了兼顾众多数据库不同的语言特性,特此开发出的功能。
    下面都是一些常规的增删改查操作,不用特意去记忆,平时敲敲也就记住了,当然重点是前面的步骤没有出现差错。
    回到helloworld/urls.py

    from django.urls import path
    
    from . import views, testdb
    
    urlpatterns = [
        path('runoob/', views.runoob),
        path('testdb/', testdb.testdb),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    /helloworld/testdb 增加数据

    from django.http import HttpResponse
    
    from TestModel.models import Test
    
    
    # 添加数据 (由于我这里在models.py中只设置了name一列)
    def testdb(request):
        test1 = Test(name='runoob')
        test1.save()
        return HttpResponse("

    数据添加成功!

    "
    )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行程序,可以看到网页显示数据添加成功,同时可以回到数据工具台,使用select语句 ,看是否成功添加。

    获取数据(查找),注意获取的时候需要循环循环for var in list 读取想要的格式,否则会报can only concatenate str (not “QuerySet”) to str错误。

    # testdb.py
    from django.http import HttpResponse
    
    from TestModel.models import Test
    
    
    # 数据库操作
    def testdb(request):
        # 初始化
        response = ""
        response1 = ""
    
        # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
        list = Test.objects.all()
    
        # filter相当于SQL中的WHERE,可设置条件过滤结果
        response2 = Test.objects.filter(name="jacin")
    
        # 获取单个对象
        response3 = Test.objects.get(id=1)
    
        # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
        Test.objects.order_by('name')[0:2]
    
        # 数据排序
        Test.objects.order_by("id")
    
        # 上面的方法可以连锁使用
        Test.objects.filter(name="runoob").order_by("id")
    
        # 输出所有数据
        for var in list:
            response1 += var.name + " "
        # response = response1
        for var in response2:
            response += var.name + " "
        return HttpResponse("

    " + response + "

    "
    )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    更新数据(改),使用save() 或者 update()

    # -*- coding: utf-8 -*-
    
    # -*- coding: utf-8 -*-
    
    from django.http import HttpResponse
    
    from TestModel.models import Test
    
    
    # 数据库操作
    def testdb(request):
        # 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
        test1 = Test.objects.get(id=1)
        test1.name = 'Google'
        test1.save()
    
        # 另外一种方式
        # Test.objects.filter(id=1).update(name='Google')
    
        # 修改所有的列
        # Test.objects.all().update(name='Google')
        re=Test.objects.filter(id=1)
        str=""
        for var in re:
            str += var.name
        return HttpResponse("

    "+str+" 修改成功

    "
    )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    删除数据

    from django.http import HttpResponse
    
    from TestModel.models import Test
    
    
    # 数据库操作
    def testdb(request):
        # 删除id=1的数据
        test1 = Test.objects.get(id=1)
        test1.delete()
    
        # 另外一种方式
        # Test.objects.filter(id=1).delete()
    
        # 删除所有数据
        # Test.objects.all().delete()
    
        return HttpResponse("

    删除成功

    "
    )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Django表单

    html表单是网站交互性的经典方式。可以查看此处链接点击此处
    http协议以请求-回复 方式工作的,发送请求的时候可以附加数据,服务器通过解析请求,可以获得传来的数据,并根据url来提供特定的服务。

    GET方法

    helloworld/helloworld/search.py

    from django.http import HttpResponse
    from django.shortcuts import render
    # 表单
    def search_form(request):
        return render(request, 'search_form.html')
     
    # 接收请求数据
    def search(request):  
        request.encoding='utf-8'
        if 'q' in request.GET and request.GET['q']:
            message = '你搜索的内容为: ' + request.GET['q']
        else:
            message = '你提交了空表单'
        return HttpResponse(message)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    /helloworld/templates/search_form.html
    注意action 属性是提交的位置,这里的search下面url跳转的地址

     <form action="/search/" method="get">
            <input type="text" name="q">
            <input type="submit" value="搜索">
     </form>
    
    • 1
    • 2
    • 3
    • 4

    /urls.py

    from django.conf.urls import url
    from . import views,testdb,search
     
    urlpatterns = [
        url(r'^hello/$', views.runoob),
        url(r'^testdb/$', testdb.testdb),
        url(r'^search-form/$', search.search_form),
        url(r'^search/$', search.search),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    POST方法

    get:视图显示和请求处理分成两个函数处理
    其实提交数据更常使用post,使用url+处理函数
    /helloworld/templates/post.html:
    csrf_token:django提供的防止伪装提交的功能,post方法提交的表格,必须有此标签

    <form action="/search-post/" method="post">
            {% csrf_token %}
            <input type="text" name="q">
            <input type="submit" value="搜索">
    </form>
    
    <p>{{ rlt }}</p>  <!--预留位置,为表格处理结果预留-->
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    /helloworld/helloworld/search2.py

    # -*- coding: utf-8 -*-
    
    from django.shortcuts import render
    from django.views.decorators import csrf
    
    
    # 接收POST请求数据
    def search_post(request):
        ctx = {}
        if request.POST:
            ctx['rlt'] = request.POST['q']
        return render(request, "post.html", ctx)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    强调一下,需要加上search-post后面的斜杠,否则读取不到

    # urls.py +
     path('search-post/',search2.search_post),
    
    • 1
    • 2

    get和post的区别

    get: 提交的数据小于1024字节,表单提交时表单数据将在地址栏显示
    post:传递数量不限制,提交数据会隐藏,安全性能较高,对信息也做了隐藏。

    Request 对象

    每个视图第一个参数是一个HttpRequest对象

    from django.http import HttpResponse
    
    def runoob(request):
    	return HttpResponse("hello world")
    
    • 1
    • 2
    • 3
    • 4

    path : 请求页面的全路径,不包括域名
    method : repuest.method == ‘GET’ ‘POST’
    cookies: 包含所有cookies的标准python字典对象
    meta:包含所有http头部信息的字典
    session:唯一可读写的属性

    Django视图

    视图函数,接受web请求并返回web响应。响应可以是html页面等。
    视图有两个重要的对象,分别是请求对象 request 与 HttpResponse
    请求对象 (HttpRequest对象)

    GET

    数据类型是QuerDict,类似于字典的对象,取值格式: 对象.方法,get()

    def runoob(request):
    	name = request.GET.get("name")
    	return HttpResponse('name:{}'.format(name))
    
    • 1
    • 2
    • 3

    POST

    数据类型和GET一致

    def runoob(request):
    	name = request.POST.get("name")
    	return HttpResponse('name:{}'.format(name))
    
    • 1
    • 2
    • 3

    path

    获取URL的路径,数据类型是字符串

    def runoob(request):
    	name=request.path
    	print(name)
    	return HttpResponse("name")
    
    • 1
    • 2
    • 3
    • 4

    method

    获取当前请求的方式,数据类型为字符串,结果大写

    def runoob(request):
    	name = request.method
    	print(name)
    	return HttpResponse("name")
    
    • 1
    • 2
    • 3
    • 4

    Django路由

    路由就是根据用户请求的URL来判断对应的处理程序,并返回处理结果,即URL与Django的视图建立映射关系
    path:普通路径,不需要自己手动添加正则首位限制符号,底层添加
    re_path: 正则路径 ,需要手动添加正则首位限制符号

    关于正则表达式,我将单独出一期笔记

    无名分组

    正则路径的无名分组,按位置传参,一一对应
    views除了request ,其他行参数量与urls中的分组数量一致
    下面的路径就是index/year(具体的日期)

    # views.py
    from django.shortcuts import HttpResponse
    
    def index(request,year):
    	print(year)
    	return HttpResponse("name")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    # urls.py
    urlpatterns = [
    	path('admin/',admin.site.urls),
    	re_path("^index/[0-9]{4}/$",view.index),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    有名分组

    故名思义,有名分组按照关键字传参,与顺序无关

    (?P<组名> 正则表达式)
    # views.py
    from django.shortcuts import HttpResponse
    def index(request, year, month): 
        print(year,month) # 一个形参代表路径中一个分组的内容,按关键字对应匹配 
        return HttpResponse('name')
    
    # urls.py
    
    re_path("^index/(?P[0-9]{4}/(?P[0-9]{2}/$",views.index)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    路由分发(include)

    问题:django 项目多个app目录使用一个urls会造成混淆,后期维护也不方便
    解决:使用路由转发,每个app目录都有urls

    from app01 import views
    # urls.py
    	path("app01/",include("app01.urls"))
    
    
    • 1
    • 2
    • 3
    • 4

    反向解析

    随着功能的增加,路由层的url发生变化,需要修改对应的视图层和模版层的url,比较麻烦
    可以利用反向解析,当url发生变化可以反向解析,一般用在模版中的超链接及视图中的重定向

    普通连接

    # 
    path("login1/",view.login,name="login")
    
    # 在views.py ,从urls 引入reverse
    return redirect(reverse("login"))
    
    #templates/ .html
    <form action="{% url 'login' %}" method="post">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    正则路径(无名分组)

    # urls.py
    re_path(r"^login/([0-9]{2})/$",views.login,name="login")
    
    # views.py
    # 引入reverse 利用reverse("路由别名“,args=(符合正则匹配的参数,))
    return redirect(reverse("login",args=(10,)))
    
    #/templates/ .html
    <form action={% url 'login' 10 %}" method="post">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    正则路径(有名分组)

    # urls.py
    re_path(r"^login/(?[0-9]{4}/$",views.login,name="login")
    
    # views.py
    return redirect(reverse("login",kwargs={"year":3333}))
    
    # html
    <form action="{% url 'login' year=3333 %}" method="post">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    命名空间

    故名思义,和其他的编程语言类似。是标识符空间定义
    普通路径

    include(("app名称:urls","app名称"))
    
    • 1
  • 相关阅读:
    JavaWeb学习笔记(缺MVC架构模式)
    华为OD机考:0036-0037-最多组团数--作业总时长
    沈阳农业大学计算机考研资料汇总
    【网页前端】CSS样式表进阶之伪元素
    分享一下如何制作专业的手绘电子地图
    【Mysql】Innodb数据结构(四)
    运算符与分支、循环语句
    市场开始复苏,三星传调涨内存芯片高达20% | 百能云芯
    华为OD机试 - 用连续自然数之和来表达整数 - 滑动窗口(Java 2023 B卷 100分)
    Windows系统Bat命令批量重命名文件
  • 原文地址:https://blog.csdn.net/QAZJOU/article/details/125989130