Django 3 版本系列的 LTS(长期支持版本)立刻就要在 4 月份发布,这个版本将会陪伴咱们两年之久。在新版本发布前夕来提早了解下有哪些有趣的新功能,这些功能在发布时应该不会变更了。css
截止到 3 月 9 日,已发布Django beta2版本。Django 3.2 仅支持 Python3.六、3.七、3.8 和 3.9,安装时注意 Python 版本。html
一、建立虚拟环境python
$ mkdir django3 $ cd django3 $ python3.6 -m venv venv $ source venv/bin/activate
二、安装 django3.2 b1mysql
(venv) $ pip install git+https://github.com/django/django@3.2b1
三、建立新的项目和 app ,防止你本地环境影响,这里直接使用虚拟环境中的命令来建立git
(venv) $ venv/bin/django-admin startproject django3 (venv) $ cd django3 (venv) $ python manage.py startapp blog
四、将 app 添加到 settings。github
# settings.py INSTALLED_APPS = [ # ... 'blog', ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django3', 'USER': 'root', 'PASSWORD': 'Root1024', 'HOST': '127.0.0.1', 'PORT': '3306', } }
五、建立 model 用来测试:sql
from django.db import models class Blog(models.Model): title = models.CharField(max_length=1000) create_at = models.DateTimeField()
六、生成数据表:数据库
(venv) $ python manage.py makemigrations (venv) $ python manage.py migrate
七、随便构造点数据:express
import string import datetime import random import pytz import os import sys BASE_DIR = os.path.dirname(os.path.dirname(__file__)) sys.path.append(os.path.join(BASE_DIR, '..')) os.environ['DJANGO_SETTINGS_MODULE'] = 'django3.settings' import django django.setup() from blog.models import Blog starting_at = pytz.UTC.localize(datetime.datetime(2020, 1, 1)) DAY = datetime.timedelta(days=1) Blog.objects.bulk_create((Blog( title=''.join(random.choices(string.ascii_letters + ' ' * 10, k=random.randint(10, 20))), create_at=starting_at + (DAY * random.random() * 365), ) for _ in range(10000)))
好了,如今咱们有 Django3.2 的环境了,下面开始搞起。django
在以前的版本中,当模型中没有定义主键时,django 会自动增长一个类型为 AutoField 的字段 id 做为主键,它是 IntegerField 的子类,范围为-2147483648 to 2147483647 。
在 Django 3.2 版本中,自增主键的类型替换为 BigAutoField 范围为 1 to 9223372036854775807。除此以外,在settings
配置中显式的增长了 DEFAULT_AUTO_FIELD
变量。若你不想修改源数据库的字段类型话,在升级时,在settings
中最好显式的添加以下配置:
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
在自定义 admin 模型展现字段的时候,以前是在所需字段直接赋值,如今使用 display 使代码变得更优雅。
# docs see https://docs.djangoproject.com/en/dev/releases/3.2/#new-decorators-for-the-admin-site from django.contrib import admin from .models import Blog @admin.register(Blog) class BlogAdmin(admin.ModelAdmin): list_display = ( 'id', 'create_at', 'create_at_year', 'title', ) # 老的实现方式 # def create_at_year(self, obj: Blog) -> str: # return obj.create_at.year # create_at_year.admin_order_field = 'create_at__year' # create_at_year.short_description = 'Year created' @admin.display(ordering='create_at__year', description='Year created') def create_at_year(self, obj: Blog) -> str: return obj.create_at.year
admin 的样式颜色采用了 css 变量来定义,咱们能够直接从新 base.html 模板,在其中定义 css 变量便可,不用再去从新覆盖具体的 css 文件。官网的例子:
{% extends 'admin/base.html' %} {% block extrahead %}{{ block.super }} <style> :root { --primary: #9774d5; --secondary: #785cab; --link-fg: #7c449b; --link-selected-fg: #8f5bb2; } </style> {% endblock %}
咱们会看到以下的 admin 页面。
咱们可使用JSONOject
功能函数实现自定义 json 字段的功能,以下 blog 对象实例多了一个 json 格式的 json_obj 字段:
>>> from django.db.models.functions import JSONObject, Lower, TruncDay >>> import pytz >>> Blog.objects.annotate(json_obj=JSONObject(title=Lower('title'), creat_year=TruncDay('create_at', tzinfo=pytz.UTC))) >>> blog = Blog.objects.annotate(json_obj=JSONObject(title=Lower('title'), creat_year=TruncDay('create_at', tzinfo=pytz.UTC))).first() >>> blog.json_obj {'title': 'zjy dqaiab ', 'creat_year': '2020-02-12 00:00:00.000000'}
Django3.2 分页器 Paginator
对象增长了get_elided_page_range
方法 ,它相似page_range
,输出的是页数区间的生成器,会根据配置将中间页数用省略号代替。该方法有两个参数on_each_side
和on_ends
,省略号前边显示页数个数为on_each_side
+1,省略号后边页数个数为on_ends
。之后咱们在写分页的时候,不再用本身处理了,期待。
>>> from django.core.paginator import Paginator >>> page_obj = Paginator(blogs, page_size) >>> page_obj.get_elided_page_range(on_each_side=3, on_ends=2) <generator object Paginator.get_elided_page_range at 0x10fb2f620> >>> list(page_obj.get_elided_page_range(on_each_side=3, on_ends=2)) [1, 2, 3, 4, '…', 999, 1000]
QuerySet.select_for_update()
查询锁的实现,目前支持不是很好,须要的数据库版本都比较高。「Currently, the postgresql, oracle, and mysql database backends support select_for_update(). However, MariaDB 10.3+ supports only the nowait argument and MySQL 8.0.1+ supports the nowait, skip_locked, and of arguments. The no_key argument is supported only on PostgreSQL.」期待后续更新吧。总的来讲 Django3.2 并无大的更新,延续了 3.1 的不少功能,对 Model 性能和实用性方面作了很多优化,针对 postgreSQL 偏多,有些功能要求 mysql 版本都在 8.0 以上。期待的异步功能并无更新,看来“异步 Django”的愿望实现还须要时间。
上边完整代码可从 github 获取,地址为 https://github.com/pylixm/django_32_demo
好了,今天的分享就到这里吧,欢迎留言讨论你觉着超赞的 Django 新功能~
我是 DeanWu,一个努力成为真正 SRE 的人。
关注公众号「码农吴先生」, 可第一时间获取最新文章。回复关键字「go」「python」获取我收集的学习资料,也可回复关键字「小二」,加我 wx 拉你进技术交流群,聊技术聊人生~