Django3.0
简介
Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发。以下内容简要介绍了如何使用 Django 实现一个数据库驱动的 Web 应用。
Django3.0发布说明:
-
Python兼容性
Django 3.0 仅支持Python 3.6, 3.7和3.8,而且仅支持每个系列里的最新版本。而Django 2.2.x是最后的支持Python 3.5的版本。Django官方已经建议第三方应用开发者放弃兼容Django2.2之前的版本,并给出了操作指南。
-
Django 3.0的新特性(Django3.0新特性 https://blog.csdn.net/weixin_43116910/article/details/103379000)
-
支持MariaDB Django现在官方支持MariaDB 10.1及以上版本
-
支持 ASGI Django 3.0已经完全自持async应用了。并提供了部署异步应用的说明
-
在PostgreSQL上支持ExclusionConstraint
-
Filter 表达式
-
model field的choices属性现在支持自定义枚举类型
-
-
一些小变更:
1. django.contrib.admin ModelAdmin.list*display 增加了 admin*order*filed;新的ModelAdmin.get*_inlinces()方法支持基于request或者model实例来指定inlines;Select2升级到4.0.7;jQuery升级到3.4.1 2. django.contrib.auth PasswordResetConfirmView添加了reset_*url_*token属性,可以在reset URL上显示一个token参数;为了支持认证backend的定制,增加了基类 BaseBackend;为了和get_*group_*permissions()对应,添加了get_*user_*permissions()方法;在django.contrib.auth.forms的password、username、和email字段上添加了 autocomplate HTML属性,以便更好地和浏览器的密码管理功能交互;当在命令行的非交互模式下,没有提供某些createsuperuser的参数时,将从环境变量读取这些参数; REQUIRED*FIELDS现在支持ManyToManyField;新方法 UserManager.with_*perm()返回特定权限的用户;PBKDF2密码哈希器迭代次数从15万次增加到18万次。 3. django.contrib.gis 允许MySQL的空间查询函数在只是的空间中操作,之前限制在绑定的盒子上;增加了GeometryDistance函数,支持PostGIS;在Distance上支持长度单位furlong;支持在pathlib.Path上使用GEOIP_PATH;GeoIP2类现在接受 pathlib.Path 4. django.contrib.postgresql 5. django.contrib.sessions 新的get_*session_cookie_age()允许动态地获取session的cookie age* 6. django.contrib.syndication 添加了 language类属性在django.contrib.syndication.views.Feed上,支持自定义feed的语言。默认值是get_language()而不是之前的LANGUAGE_CODE。* 7. cache add_never_cache_headers()和never_cache() 增加了private指令 到 Cache-Control* 8. File Storage Storage.get_alternative_name()允许自动以生成文件名的算法,当上传的文件名已经存在的时候* 9. Form 10. I18N 11. Logging
- 非兼容变更
- Database backend API
- django.contrib.admin
- django.contrib.gis
- 不再支持PostgreSQL 9.4,django支持PostgreSQL 9.5及以上版本
- 不再支持Oracle 12.1,django 3.0支持 Oracle 12.2和18c
- 移除一些私有的Python 2 兼容的API
- 移除的特性
以下特性已经到达了最后的维护期限,所以在Django 3.0 中已经移除
- django.db.backends.postgresql_psycopg2 模块被移除
- django.shortcuts.render_to_response被移除
- DEFAULT_CONTENT_TYPE设置被移除
- HttpRequest.xreadlines() 被移除
- Field.from_db_value()和Expression.convert_value()中的context参数被移除
- QuerySet.earliest()和latest()的关键字参数field_name 被移除
- ForceRHR函数被移除
- django.utils.http.cookie_date() 被移除
- staticfiles和admin_static模板标签库被移除
- django.contrib.staticfiles.templatetags.staticfiles.static()被移除
一般情况下,新发布的版本在随后的较短时间内可能会发布bug的修复版,本人并不建议立刻从Django 2.2升级到3.0,可以再过2-3个月;如果项目还在使用Django 2.0.x,2.1.x,可以先升级到 Django 2.2的最新版。
准备
-
安装Python
注意:Django 3.0 仅支持Python 3.6, 3.7和3.8,而且仅支持每个系列里的最新版本。
-
配置虚拟环境
# anaconda创建虚拟环境 conda create -n <虚拟环境名称> python=3.8 # 进入/切换到指定名称的虚拟环境,如果不带任何参数,则默认回到全局环境base中。 conda activate <虚拟环境名称> # 退出当前虚拟环境 conda deactivate
-
设置数据库
此步骤仅在你打算使用诸如 PostgreSQL, MariaDB, MySQL, 或者 Oracle 这些大型数据库引擎时需要。
安装
-
虚拟环境中安装Django3.0
pip install django==3.0
-
验证
创建Django项目
创建项目目录
mkdir djangodemo
cd djangodemo
命令创建Django项目
django-admin startproject mysite #项目名称为mysite
startproject创建了以下内容:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
这些目录和文件的用处是:
- 最外层的
mysite/
根目录只是你项目的容器, 根目录名称对Django没有影响,你可以将它重命名为任何你喜欢的名称。 manage.py
: 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin and manage.py 获取所有manage.py
的细节。- 里面一层的
mysite/
目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如mysite.urls
). mysite/__init__.py
:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,阅读官方文档中的 更多关于包的知识。mysite/settings.py
:Django 项目的配置文件。如果你想知道这个文件是如何工作的,请查看 Django 配置 了解细节。mysite/urls.py
:Django 项目的 URL 声明,就像你网站的“目录”。阅读 URL调度器 文档来获取更多关于 URL 的内容。mysite/asgi.py
:作为你的项目的运行在 ASGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署 了解更多细节。mysite/wsgi.py
:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署 了解更多细节。
路由基本定义
-
路由:需要创建一个Python 模块,通常被称为URLconf(URL configuration)。这个模块是纯粹的Python 代码,包含URL 模式(简单的正则表达式)到Python 函数(你的视图)的简单映射。
-
Django对于请求的处理过程:
1.Django 确定使用根 URLconf 模块。通常,这是
ROOT_URLCONF
设置的值,但如果传入HttpRequest
对象拥有urlconf
属性(通过中间件设置),它的值将被用来代替ROOT_URLCONF
设置2.Django 加载该 Python 模块并寻找可用的 urlpatterns 。它是 django.urls.path() 和(或) django.urls.re_path() 实例的序列(sequence)。
3.Django 会按顺序遍历每个 URL 模式,然后会在所请求的URL匹配到第一个模式后停止,并与 path_info 匹配。
4.一旦有 URL 匹配成功,Djagno 导入并调用相关的视图,这个视图是一个Python 函数(或基于类的视图 class-based view )。视图会获得如下参数:
*一个 HttpRequest 实例。
*如果匹配的 URL 包含未命名组,那么来自正则表达式中的匹配项将作为位置参数提供。
*关键字参数由路径表达式匹配的任何命名部分组成,并由 django.urls.path() 或 django.urls.re_path() 的可选 kwargs 参数中指定的任何参数覆盖。
5.如果没有 URL 被匹配,或者匹配过程中出现了异常,Django 会调用一个适当的错误处理视图。参加下面的错误处理( Error handling )。
路由示例:
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
- 要从 URL 中取值,使用尖括号。
- 捕获的值可以选择性地包含转换器类型。比如,使用
<int:name>
来捕获整型参数。如果不包含转换器,则会匹配除了/
外的任何字符。 - 这里不需要添加反斜杠,因为每个 URL 都有。比如,应该是
articles
而不是/articles
。
一些请求的例子:
-
/articles/2005/03/
会匹配 URL 列表中的第三项。Django 会调用函数views.month_archive(request, year=2005, month=3)
。 -
/articles/2003/
would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the functionviews.special_case_2003(request)
-
/articles/2003
would not match any of these patterns, because each pattern requires that the URL end with a slash. -
/articles/2003/03/building-a-django-site/
会匹配 URL 列表中的最后一项。Django 会调用函数views.article_detail(request, year=2003, month=3, slug="building-a-django-site")
。
路径转换器
下面的路径转换器在默认情况下是有效的:
str - 匹配除了 '/' 之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。
int - 匹配 0 或任何正整数。返回一个 int 。
slug - 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。比如,building-your-1st- django-site 。
uuid - 匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为 小写。比如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。
path - 匹配非空字段,包括路径分隔符 '/' 。它允许你匹配完整的 URL 路径而不是像 str 那样匹配 URL 的一部分。
自定义的路径转换器
方式一:
转换器是一个类,包含如下内容:
- 字符串形式的
regex
类属性。 to_python(self, value)
方法,用来处理匹配的字符串转换为传递到函数的类型。如果没有转换为给定的值,它应该会引发ValueError
。ValueError
说明没有匹配成功,因此除非另一个 URL 模式匹配成功,否则会向用户发送404响应。to_url(self, value)
,处理将 Python 类型转换为 URL 中要使用的字符串。
例如:
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
在 URLconf 中使用 register_converter()
来注册自定义的转换器类:
from django.urls import path, register_converter
from . import converters, views
register_converter(converters.FourDigitYearConverter, 'yyyy')
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<yyyy:year>/', views.year_archive),
...
]
方式二 正则表达式:
使用正则表达式:
如果路径和转化器语法不能很好的定义你的 URL 模式,你可以可以使用正则表达式。如果要这样做,请使用 re_path()
而不是 path()
。
在 Python 正则表达式中,命名正则表达式组的语法是 (?P<name>pattern)
,其中 name
是组名,pattern
是要匹配的模式。
这里是先前 URLconf 的一些例子,现在用正则表达式重写一下:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[w-]+)/$', views.article_detail),
]
这实现了与前面示例大致相同的功能,除了:
- 将要匹配的 URLs 将稍受限制。比如,10000 年将不在匹配,因为 year 被限制长度为4。
- 无论正则表达式进行哪种匹配,每个捕获的参数都作为字符串发送到视图。
当从使用 path()
切换到 re_path()
(反之亦然),要特别注意,视图参数类型可能发生变化,你可能需要调整你的视图。
使用未命名的正则表达式组:
有命名组语法,例如 (?P<year>[0-9]{4})
,你也可以使用更短的未命名组,例如 ([0-9]{4})
。
不是特别推荐这个用法,因为它会更容易在匹配的预期含义和视图参数之间引发错误。
在任何情况下,推荐在给定的正则表达式里只使用一个样式。当混杂两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。
正则嵌套参数: