Django1和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.Django2特有的url
url规则:
- path写的是绝对字符串,请求地址必须与路由地址完全匹配
- 使用尖括号 <> 从url中获取参数值
- 可以使用转换器指定参数类型,例如: <int:age> 捕获一个整数参数age,
若果没有转化器,将匹配任何字符串,也包括路径分隔符 / - 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
自定义转换器:
步骤:
- 自定义一个类
- 类中必须有:类属性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):
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了。
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')
Django2.0:hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE)
Django1和2的区别的更多相关文章
- Django 应用程序 + 模型 + 基本数据访问
如果你只是建造一个简单的web站点,那么可能你只需要一个app就可以了.如果是复杂的象 电子商务之类的Web站点,你可能需要把这些功能划分成不同的app,以便以后重用. 确实,你还可以不用创建app, ...
- django之表设计、路由层等
图书管理系统表的设计 from django.db import models # Create your models here. class Book(models.Model): title = ...
- urls 视图层
urls.py 路由层 路由与视图函数对应关系 >>> 路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射 ...
- 如何在Django1.6结合Python3.4版本中使用MySql
唉,最近赶了个新潮,用起了Python3.4跟Django1.6,数据库依然是互联网企业常见的MySql. 悲催的是在Python2.7时代连接MySql的MySQLdb还不支持Python3.4,还 ...
- 【updating】python读书笔记-The Django Book2.0(for django1.4)
原文:http://www.djangobook.com/en/2.0/frontmatter.html 译文:http://djangobook.py3k.cn/2.0/ 或者http://docs ...
- Django-1版本的路由层、Django的视图层和模板层
一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...
- 如何在Django1.6结合Python3.3版本中使用MySql
用起了Python3.4跟Django1.6,数据库依然是互联网企业常见的MySql. 悲催的是在Python2.7时代连接MySql的MySQLdb还不支持Python3.4,还好,苦苦追问G哥终于 ...
- Django--1、MTV及基本应用
web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,以避免重复造轮子. 所有的Web应用,本质上是一个socket服务 ...
- Django中render_to_response和render的区别(转载)
转载地址:https://www.douban.com/note/278152737/ 自django1.3开始:render()方法是render_to_response的一个崭新的快捷方式,前者会 ...
随机推荐
- 链接脚本再探和VMA与LMA
链接脚本简单描述 连接脚本的描述都是以节(section)的单位的,网上也有很多描述链接脚本语法的好文章,再不济还有官方的说明文档可以用来学习,其实主要就是对编译构建的整个过程有了深入的理解后就能对链 ...
- CN_Week2_Neuron_code
CN_Week1_Neuron_code on Coursera Abstract for week2: -- 1. Technique for recording from the brain. - ...
- Python+OpenCV+图片旋转并用原底色填充新四角
import cv2 from math import fabs, sin, cos, radians import numpy as np from scipy.stats import mode ...
- short URL 短网址实现原理剖析
short URL 短网址实现原理剖析 意义,简短便于分享,避免出现超长 URL 的字符长度限制问题 原理分析, 使用 HashMap 存储对应的映射关系 (长度不超过7的字符串,由大小写字母加数字共 ...
- UI Design & App & Free Icons
UI Design & App & Free Icons icons8 https://icons8.com https://icons8.com/ouch Ouch可以帮助那些不进行 ...
- vue & npm & components & plugins
vue & npm & components & plugins how to publish an vue ui component to npm? https://www. ...
- js 最简单的发布订阅模式
let _subscriber: any; function autorun(subscriber: Function) { _subscriber = subscriber; _subscriber ...
- 鸿蒙的js开发部模式16:鸿蒙布局Grid网格布局的应用一
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口]目录:1.Grid简介2.使用Grid布局实现的效果3.grid-row-gap和grid-colunm-gap属性4.< ...
- 主键策略+mybayisPlus自动增长
主键策略: 1.自动增长 有一点小缺陷:例如当一张表里的数据过于庞大时我们会进行分表操作,若是用自动增长策略,那么除了第一张表外的每一张表都必须知道上一张的表的的最后ID值.这个操作便会造成效率的变低 ...
- luogu4464:莫比乌斯反演,积性函数和伯努利数
题目链接:https://www.luogu.com.cn/problem/P4464 简记$gcd(x,y)=(x,y)$. 推式子: $\sum_{i=1}^{n}{(i,n)^xlcm(i,n) ...