zoukankan      html  css  js  c++  java
  • Django1.x与Django2.0常用功能区别

    Django1.x与Django2.0常用功能区别

    一、路由的区别

    1、Django1中的url

    1. 使用url
    2. url写的是正则,模糊匹配
    3. 使用(d+)(?P<name>d+)实现分组,从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.Django2特有的url

    url规则:

    1. 使用path
    2. path写的是绝对字符串,请求地址必须与路由地址完全匹配
    3. 使用尖括号 <> 从url中获取参数值
    4. 可以使用转换器指定参数类型,例如: int:age 捕获一个整数参数age,
      若果没有转化器,将匹配任何字符串,也包括路径分隔符 /
    5. 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
    

    3、自定义转换器

    步骤:

    1. 自定义一个类

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

      • regex:类属性,字符串类型

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

      • 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):
            # url反向解析
            return '%2s' % value
    
    
    # 在主路由 urls.py 下导入,生成转换器
    from django.urls import register_converter
    
    register_converter(Date,'date')   # 注册转换器
    
    path('full-year/<date:full_year>/',views.full_year, name="full_year")
    

    4、Django2的url兼容了Django1的写法

    • Django2中的re_path与Django中的url用法完全相同
    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。

    • 语法:namespace:url_name'

    例如:

    # 项目中的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了。
    

    2、Django2

    1)基本使用

    # 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),
    ]
    

    2)某些前缀一致的情况

    # 这种方法可以用来去除URLconf中的冗余,其中某个模式前缀被重复使用。例如,考虑这个URLconf:
    
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('<page_slug>-<page_id>/history/', views.history),
        path('<page_slug>-<page_id>/edit/', views.edit),
        path('<page_slug>-<page_id>/discuss/', views.discuss),
        path('<page_slug>-<page_id>/permissions/', views.permissions),
    ]
    我们可以改进它,通过只声明共同的路径前缀一次并将后面的部分分组:
    
    from django.urls import include, path
    from . import views
    
    urlpatterns = [
        path('<page_slug>-<page_id>/', include([
            path('history/', views.history),
            path('edit/', views.edit),
            path('discuss/', views.discuss),
            path('permissions/', views.permissions),
        ])),
    ]
    

    3)反向解析

    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('articles/<int:year>/', views.year_archive, name='archive'),
    ]
    
    根据这种设计,对应于年度归档文件的URL是 /articles/<nnnn>/
    
    
    你可以使用以下方法在模板代码中获取这些:
    <a href="{% url 'archive' 2012 %}">2012 Archive</a>
    
    
    或者在Python代码中:
    
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    
    def redirect_to_year(request):
        year = 2006
        return HttpResponseRedirect(reverse('archive', args=(year,)))
    

    4)命名空间

    注意:如果直接使用name做反向解析(即使用了include),也不需要设置app_name,但是使用namespace,需要设置app_name
    
    # 1.项目的urls
    from django.urls import path, include
    
    
    urlpatterns = [
        path('myapp/', include('MyApp.urls', namespace='my')),
        path('yourapp/', include('YourApp.urls', namespace='you')),
    ]
    
    # 2.1 MyApp.urls.py
    from django.urls import path
    from MyApp import views
    
    app_name = 'myxxx'  # 在各个APP级别的urls中设置app_name
    
    urlpatterns = [
        path('index/', views.index, name="index"),
        path('home/', views.home, name="home"),
    ]
    
    # 2.2 MyApp.Views.py
    from django.shortcuts import render, redirect, HttpResponse
    from django.urls import reverse
    
    
    def index(request):
        return HttpResponse("MyApp-index")
    
    
    def home(request):
        print("home")
        return redirect(reverse('my:index'))
        # return redirect(reverse('myxxx:index'))  # 也可以使用app_name
    
    # 3.1 YourApp.urls.py
    from django.urls import path
    from YourApp import views
    
    app_name = 'yourxxx'  # 在各个APP级别的urls中设置app_name
    
    urlpatterns = [
        path('index/', views.index, name="index"),
        path('hello/', views.hello, name="hello"),
    ]
    
    
    # 3.2 YourApp.Views.py
    from django.shortcuts import render, redirect, HttpResponse
    from django.urls import reverse
    
    
    def index(request):
        return HttpResponse("YourApp-index")
    
    
    def hello(request):
        print("hello")
        return redirect(reverse('you:index'))
        # return redirect(reverse('yourxxx:index'))  # 也可以使用app_name
    
    # 4. 在模板中使用
    <a href="{% url 'my:index' %}">myapp-index</a>  # 可以写namespace
    <a href="{% url 'yourxxx:index' %}">your-index</a>  # 可以写app_name
    

    三、其他的一些区别

    1、ORM外键

    Django1.0:hbook = models.ForeignKey('BookInfo')  # 1中默认是级联的
    Django2.0:hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE)  # 2中需要手动设置级联
    

    转载于:https://www.cnblogs.com/Zzbj/p/11150041.html

  • 相关阅读:
    springmvc源码分析上之HandlerMapping
    java web api接口调用
    centos6 hadoop2.7.3分布式搭建
    大话java基础知识一之为什么java的主函数入口必须是public static void
    jQuery引用
    windows 服务的卸载
    java 环境安装
    python matplotlib 折线图的制作
    python matplotlib 简单柱状图的制作
    python 安装库时 Failed building wheel for 错误处理
  • 原文地址:https://www.cnblogs.com/linagcheng/p/13523380.html
Copyright © 2011-2022 走看看