Python学习第120天(Django1和2之间的区别)

Posted 崆峒山肖大侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习第120天(Django1和2之间的区别)相关的知识,希望对你有一定的参考价值。

昨天实操了Django之后,发现课程中讲到的Django1和我目前使用的Django2之间还是存在很多区别的,所以今天就多浪费了一些流量,加上自己试了一些结果,暂时总结一下之间的区别吧。

一、先说一下Django中url分发的问题,这个2中明显更为优秀,但是我还不怎么会用,教学视频也没有讲到。

  1.Django1中的url

from django.conf.urls import url

# 使用url关键字
urlpatterns = [
    url(article-(d+).html,views.article),
    url(article-(?P<article_id>d+).html,views.article)
]
# url请求地址为:http://127.0.0.1:8000/article-1.html

Django1的url支持正则匹配:
article-(d+).html:使用正则表达式的分组匹配来获取URL中的参数,并以位置参数形式传递给视图article。
article-(?P<article_id>d+).html:使用正则表达式的分组命名匹配来获取URL中的参数,并以关键字参数的形式传递给视图article。

分组命名正则表达式组的语法是:(?P<name>pattern),其中name是组的名称(视图中的关键字参数必须跟组名一致),pattern是正则表达式。

  2.Django2中的url

    (1)2中所特有的url写法

      url书写规则:

        1.path写的是绝对字符串,请求地址必须与路由地址完全匹配

        2.使用尖括号 <> 从url中获取参数值

        3.可以使用转换器指定参数类型,例如: <int:age> 捕获一个整数参数age,若果没有转化器,将匹配任何字符串,也包括路径分隔符 /

        4.path拥有5个转换器:

          str:匹配除路径分隔符 / 外的字符串

          int:匹配自然数

          slug:匹配字母,数字,横杠及下划线组成的字符串

          uuid:匹配uuid形式的数据

          path:匹配任何字符串,包括路径分隔符 /

from django.urls import path

# 使用path关键字
urlpatterns = [
    path(article-<int:article_id>.html,views.article),
]
# url请求地址为:http://127.0.0.1:8000/article-1.html

      自定义转换器:

        步骤:

          1.自定义一个类

          2.类中必须有:类属性regex,to_python方法,to_url方法

          3.regex:类属性,字符串类型

          4.to_python(self, value)方法:value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。

          5.to_url(self, value)方法:和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

class Date:
    regex = ^0?[1-9]$|^1[0-2]$
    
    def to_python(self, value):
        # 可以写你的逻辑,对匹配到的字符串进行处理
        value = 2019/ + value
        return value
        
    def to_url(self, value):
        return %2s % value

# 在主路由下导入,生成转换器
from django.urls import register_converter

register_converter(Date,date)

path(full-year/<date:full_year>/,views.full_year, name="full_year")

  2.Django2的url兼容了Django1的写法

from django.urls import re_path
这里的re_path的用法跟Django1的url用法视完全一样的,匹配正则。

urlpatterns = [
    path(articles/2003/, views.special_case_2003),  # Django2的写法
    re_path(articles/(?P<year>[0-9]{4})/, views.year_archive),  # 兼容Django1的写法
    re_path(articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/, views.month_archive),
    re_path(articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[^/]+)/, views.article_detail),
]

  后面可以暂时按照课程中设置的要求,先按照兼容模式书写

 

二、关于路由分发的include

  1.关于Django1

    1.include其他的URLconfs(二级路由系统)

创建两个app,每个app都创建一个urls.py

# 项目的urls.py
from django.conf.urls import url, include
from app01 import urls as app01_urls
from app02 import urls as app02_urls

urlpatterns = [
    # 二级路由系统
    url(r^app01/, include(app01_urls)),
    url(r^app02/, include(app02_urls)),
]

# app01的urls.py
from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r^book/$, views.book_list),
    url(r^book/(?P<yyyy>[0-9]{4})/$, views.book),
    url(r^blog/$, views.blog),
    url(r^blog/(?P<num>d+)/$, views.blog),
]

# app02的urls.py
from django.conf.urls import url
from app02 import views

urlpatterns = [
    url(r^index/$, views.index),
    url(r^home/$, views.home),
]

解析:在浏览器输入http://127.0.0.1:8000/app02/home/
首先会拿着app02/home/去项目的urls中匹配,找到url(r^app02/, include(app02_urls)),
看到include,就拿着home/去app02的urls中匹配,找到url(r^home/$, views.home),就访问home页面。

  这个是比较熟悉的模式

  2.命名URL和URL反向解析

    在最终的路由那里设置name属性,给这个路由设置别名,
    然后在视图函数那里导入from django.urls import reverse,
    在需要解析地址的地方使用reverse(别名),就可以解析出这个url,
    且无论路由本身的地址如何改变,只要使用reverse(别名),一样能解析出url地址

例如:

# 项目的urls.py
from django.conf.urls import url, include
from app02 import urls as app02_urls

urlpatterns = [
    # 二级路由系统
    url(r^app02/, include(app02_urls)),
]

# app02的urls.py
from django.conf.urls import url
from app02 import views

urlpatterns = [
    url(r^login/$, views.login),
    url(r^index/$, views.index, name=myindex),
]

# views.py
from django.shortcuts import render, redirect, HttpResponse
from django.urls import reverse  # 导入reverse反向解析出地址

def login(request):
    if request.method == POST:
        username = request.POST.get(username)
        pwd = request.POST.get(pwd)
        ret = UserInfo.objects.filter(username=username, pwd=pwd)
        if ret:
            return redirect(reverse(myindex))  # reverse反向解析出url地址:/app02/index/
    return render(request, login.html)    
    
def index(request):
    return HttpResponse(index)    
    
解析:在浏览器输入http://127.0.0.1:8000/app02/login/,进入登录界面,
登录成功后,redirect(reverse(myindex)),reverse会根据别名myindex自动解析出index的具体路径(http://127.0.0.1:8000/app02/index/),
而且无论index的具体路由怎么改变,reverse(myindex)总是能解析出具体的url。

注意:当url需要参数时:

1.如果index需要传位置参数:
urlpatterns = [
    url(r^index/(d+)/$, views.index, name=myindex),
]
return redirect(reverse(myindex, args=(2018,))) 2.如果index需要传关键字参数: urlpatterns = [ url(r^index/(?P<year>d+)/$, views.index, name=myindex), ]
return redirect(reverse(myindex, kwargs={year: 2019})) # 在HTML模板中使用 无参数:<a href="{% url ‘myindex‘ %}">myindex</a> 有参数:<a href="{% url ‘myindex‘ ‘2018‘ %}">myindex</a>

  3.命名空间模式

    如果不同的APP使用了相同的URL反转名称,那么reverse怎么解析?
    使用命名空间模式(namespace)可以解决这个问题,即不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。

    例如:

项目中的urls.py
from django.conf.urls import url, include
 
urlpatterns = [
    url(r^app01/, include(app01.urls, namespace=app01)),
    url(r^app02/, include(app02.urls, namespace=app02)),
]

# app01中的urls.py
from django.conf.urls import url
from app01 import views 

urlpatterns = [
    url(r^index/(?P<year>d+)/$, views.index, name=myindex),
]

# app02中的urls.py
from django.conf.urls import url
from app02 import views 

urlpatterns = [
    url(r^index/(?P<year>d+)/$, views.index, name=myindex),
]

现在,两个app中url的别名重复了,反转URL的时候就可以通过命名空间的名称得到我当前的URL。
语法:
命名空间名称:URL名称

# 在HTML模板中使用:
<a href="{% url ‘app01:myindex‘ ‘2018‘ %}">app01 myindex</a>
<a href="{% url ‘app02:myindex‘ ‘2019‘ %}">app02 myindex</a>

# 在views中的函数中使用
v = reverse(app01:myindex, kwargs={year:2018})
v = reverse(app02:myindex, kwargs={year:2019})

这样即使app中URL的命名相同,我也可以反转得到正确的URL了。

Django2部分

暂时只看了基本使用方法,后学还有对应的明天看时间吧,自己要去学习纪检知识。  

In settings/urls/main.py
from django.urls import include, path

urlpatterns = [
    path(<username>/blog/, include(foo.urls.blog)),
]

# In foo/urls/blog.py
from django.urls import path
from . import views

urlpatterns = [
    path(‘‘, views.blog.index),
    path(archive/, views.blog.archive),
]

今天内容有点多,得好好吸收啊。

 

 

  

 

以上是关于Python学习第120天(Django1和2之间的区别)的主要内容,如果未能解决你的问题,请参考以下文章

python学习第30天

Python学习路线图:120天系统学习,你也能成大神!

第120天学习打卡(MyBatisPlus 概述 特性 入门 配置日志 CRUD扩展 乐观锁)

第67天python学习基于tcp实例化实现远程执行命令

Python学习第66天(css内外边距)

python学习第十六天集合的关系测试