Django 3.2的正式发布,将是Django 3系列的最后一个稳定版本,扩展支持会一直延续到2024年。对于学习Django和使用Django开发新项目的而言,还是直接上Django最新版本。
本篇介绍Django 3.2的主要变化。
参考资料:https://docs.djangoproject.com/en/dev/releases/3.2/
Django 3.2支持Python 3.6, 3.7, 3.8和3.9。升级Django版本的同志们别忘了也升级下Python版本。
Django 3.2之前,如果对一个app修改了相应配置,应该将app.apps.AppConfig类加入到INSTALLED_APP中去,而不是直接添加app名。Django 3.2支持AppConfig名自动发现,这也就意味着如果不管以后是否修改一个app的配置,以后只需要在INSTALLED_APP中添加app名即可。
在Django 3.1及之前版本中,如果将app名加入到INSTALLED_APP里并希望apps.py里的AppConfig配置类生效,还需要修改app目录下的__init__.py, 通过default_app_config手动指定AppConfig配置类。Django 3.2以后,再也不用纠结INSTALLED_APPS中应该写app名,还是AppConfig子类了,两者将变得完全等同。default_app_config属性也将被删除。
当定义一个模型的时候,如果没有使用primary_key=True指定一个主键,Django会自动为创建一个主键。Django 3.2之前默认使用的自增主键AutoField, Django 3.2及以后将会默认使用BigAutoField。如果想依然使用AutoField,可以修改配置文件。
或者在app层面进行配置。
将BigAutoField 改为 AutoField即可
这条非常有用。对于频繁查询的字段,建议在模型的Meta选项里定义indexes索引。Django 3.2将支持使用函数表达式创建索引。
from django.db import models
from django.db.models import F, Index, Value
from django.db.models.functions import Lower, Upper
class IndexModel(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
height = models.IntegerField()
weight = models.IntegerField()
class Meta:
indexes = [
Index(
Lower('first_name'),
Upper('last_name').desc(),
name="first_last_name_idx",
),
Index(
F('height') / (F('weight') + Value(5)),
name='calc_ids',
),
]
在Django 3.2之前,如果要在admin中自定义display选项,可以通过点号. 设置排序字段及简短描述。
def is_published(self, obj):
return obj.publish_date is not None
is_published.boolean = True
is_published.admin_order_field = '-publish_date'
is_published.short_description = 'Is Published?'
在Django 3.2以后,可以使用@display装饰器添加描述。
@admin.display(
boolean=True,
ordering='-publish_date',
description='Is Published?',)
def is_published(self, obj):
return obj.publish_date is not None
在Django 3.2之前,如果要在admin中自定义actions,可以通过点号. 设置所需的权限及简单描述。
def make_published(self, request, queryset):
queryset.update(status='p')
make_published.allowed_permissions = ['publish']
make_published.short_description = 'Mark selected stories as published'
在Django3.2中,可以直接通过@action装饰器来给自定义action添加权限和描述。
@admin.action(
permissions=['publish'],
description='Mark selected stories as published',
)
def make_published(self, request, queryset):
queryset.update(status='p')
Django 3.2版本将支持Python 3.6, 3.7, 3.8和3.9。连Python 3.5都不支持了。
Django 3.2版本将放弃对MySQL 5.6, PostgreSQL 9.5及之前版本的支持。
新的django.core.cache.backends.memcached.PyMemcacheCache缓存后端允许将pymemcache库用于memcached。pymemcache需要3.4.0或更高版本。
Django 3.2之前的Paginator类将连续输出所有页码,非常不智能。Django 3.2新增get_elided_page_range方法。
Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)
使用该方法将输出如下页码范围,更容易使用。
[1, 2, '…', 7, 8, 9, 10, 11, 12, 13, '…', 49, 50]
Django自带分页类将新增get_elided_page_range方法。可以通过on_each_side和on_ends选项,实现智能分页。
Paginator.get_elided_page_range
(number, *, on_each_side=3, on_ends=2)
当的页面数非常多时,不会像现在一样所有页码都会显示。新的分页自带缩略,显示效果如下:
[1, 2, '…', 7, 8, 9, 10, 11, 12, 13, '…', 49, 50]
不得不说,这个功能实在太香了。