define定义的是什么类型_为什么Django 3后建议使用Field.choices枚举类型定义choices选项...
Django 3.0的主要新增功能之一是對模型字段選擇的枚舉。它是一種定義和約束模型Field.choices的更好方法。
以前在Django模型中通常會通過定義一些“常量”和元組來定義choices,如下所示:
from django.db import modelsclass Book(models.Model):UNPUBLISHED = 'UN'PUBLISHED = 'PB'STATUS_CHOICES = [(UNPUBLISHED, 'Unpublished'),(PUBLISHED, 'Published'),]status = models.CharField(max_length=2,choices=STATUS_CHOICES,default=UNPUBLISHED,)然后其他人可以按如下方式使用這些常量,例如:
unpublished_books = Book.objects.filter(status=Book.UNPUBLISHED)如果多個模型使用同一組選項choices和常量,則可能需要把choices選項和常量從模型級別而轉到模塊級別,此時再也不能在通過Book.UNPUBLISHED的獲取常量內容了。
from django.db import modelsUNPUBLISHED = 'UN' PUBLISHED = 'PB' STATUS_CHOICES = [(UNPUBLISHED, 'Unpublished'),(PUBLISHED, 'Published'), ]class Book(models.Model):status = models.CharField(max_length=2,choices=STATUS_CHOICES,default=UNPUBLISHED,)class Pamphlet(models.Model):status = models.CharField(max_length=2,choices=STATUS_CHOICES,default=PUBLISHED,)這樣在models.py文件中留下一堆沒有命名空間的常量, 這有點違反《 Python之禪》:
命名空間是一個很棒的主意–讓我們做更多的事!這也使我們缺少一些有用的功能。例如,沒有簡單的方法可以將值轉換為其顯示標簽。
更新(2020年1月28日): 老版模型實例Django了提供get_FOO_display()方法來轉換值choice選項值對應的標簽。
存在諸如django-choices和django-enumfields之類的軟件包來解決這些問題。我還看到了其他項目上幾個類似功能的自定義實現。
Django 3.0現在提供了一個Choices帶有兩個子類類IntegerChoices和TextChoices。這些類擴展了Python的Enum類型,并增加了額外的約束和功能,以使其適用于Field.choices。
現在我們要轉換之前的示例,我們定義一個新的Status類,該類繼承了TextChoices類,用于替換我們之前定義的STATUS_CHOICES元組。現在Status.choices與STATUS_CHOICES是等同的。除此以外,你還可以使用Status.UNPUBLISHED的方式調用Status類下的常量。此時常量UNPUBLISHED有了自己的命名空間,更安全,也使代碼可讀性更高。
class Status(models.TextChoices):UNPUBLISHED = 'UN', 'Unpublished'PUBLISHED = 'PB', 'Published'class Book(models.Model):status = models.CharField(max_length=2,choices=Status.choices,default=Status.UNPUBLISHED,)class Pamphlet(models.Model):status = models.CharField(max_length=2,choices=Status.choices,default=Status.PUBLISHED,)我們可以通過檢查未檢測到遷移變化來測試是否正確轉換:
$python manage.py makemigrations --dry-run No changes detected如果我們添加,刪除或重新排序了任何成員,則這將被檢測為字段中的更改。這是因為遷移框架僅看到由choices生成的列表Status.choices,而看不到枚舉類。
QuerySet過濾器可以更新為使用以下Choices類:
unpublished_books = Book.objects.filter(status=Status.UNPUBLISHED)我們還可以輕松地將值轉換為其顯示標簽:
In [2]: book = Book.objects.latest('id')In [3]: Status(book.status) Out[3]: <Status.UNPUBLISHED: 'UN'>In [4]: Status(book.status).label Out[4]: 'Unpublished'更干凈!
結語
我希望這可以幫助您享受這一新的Django 3.0功能。該枚舉類型的文件涵蓋了一些細節,值得一讀。感謝Shai Berger,Nick Pope,Marius Felisiak,Carlton Gibson,以及所有其他負責添加它的人(票號#27910)。
-亞當
原文鏈接:https://adamj.eu/tech/2020/01/27/moving-to-django-3-field-choices-enumeration-types/
相關閱讀
支持異步的Django 3.X來了,你準備好了嗎? Django 3.0新特色與變化詳解。
總結
以上是生活随笔為你收集整理的define定义的是什么类型_为什么Django 3后建议使用Field.choices枚举类型定义choices选项...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米笔记本引导修复_知识帖,笔记本电脑不
- 下一篇: overflowhidden把内容遮住了