Django 系列部落格(十三)

  • 2020 年 1 月 22 日
  • 筆記

Django 系列部落格(十三)

前言

本篇部落格介紹 Django 中的常用欄位和參數。

ORM 欄位

AutoField

int 自增列,必須填入參數 primary_key=True。當 model 中如果沒有自增列,則會自動創建一個列名為 id 的列。

IntegerField

一個整數類型,範圍在-2147483648 to 2147483647。

CharField

字元類型,必須提供max_length參數, max_length表示字元長度。

DateField

日期欄位,日期格式 YYYY-MM-DD,相當於Python中的datetime.date()實例。

DateTimeField

日期時間欄位,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相當於Python中的datetime.datetime()實例。

常用和非常用欄位

AutoField(Field)  - int自增列,必須填入參數  primary_key = True    BigAutoField(AutoField)  - bigint自增列,必須填入參數  primary_key = True    註:當model中如果沒有自增列,則自動會創建一個列名為id的列  from django.db import models      class UserInfo(models.Model):      # 自動創建一個列名為id的且為自增的整數列      username = models.CharField(max_length=32)      class Group(models.Model):      # 自定義自增列      nid = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      SmallIntegerField(IntegerField):  - 小整數 - 32768 ~ 32767    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)  - 正小整數  0 ~ 32767  IntegerField(Field)  - 整數列(有符號的) - 2147483648 ~ 2147483647    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)  - 正整數  0 ~ 2147483647    BigIntegerField(IntegerField):  - 長整型(有符號的) - 9223372036854775808 ~ 9223372036854775807    BooleanField(Field)  - 布爾值類型    NullBooleanField(Field):  - 可以為空的布爾值    CharField(Field)  - 字元類型  - 必須提供max_length參數, max_length表示字元長度    TextField(Field)  - 文本類型    EmailField(CharField):  - 字元串類型,Django  Admin以及ModelForm中提供驗證機制    IPAddressField(Field)  - 字元串類型,Django  Admin以及ModelForm中提供驗證  IPV4  機制    GenericIPAddressField(Field)  - 字元串類型,Django  Admin以及ModelForm中提供驗證  Ipv4和Ipv6  - 參數:  protocol,用於指定Ipv4或Ipv6, 'both', "ipv4", "ipv6"  unpack_ipv4, 如果指定為True,則輸入::ffff: 192.0  .2  .1  時候,可解析為192  .0  .2  .1,開啟此功能,需要protocol = "both"    URLField(CharField)  - 字元串類型,Django  Admin以及ModelForm中提供驗證  URL    SlugField(CharField)  - 字元串類型,Django  Admin以及ModelForm中提供驗證支援  字母、數字、下劃線、連接符(減號)    CommaSeparatedIntegerField(CharField)  - 字元串類型,格式必須為逗號分割的數字    UUIDField(Field)  - 字元串類型,Django  Admin以及ModelForm中提供對UUID格式的驗證    FilePathField(Field)  - 字元串,Django  Admin以及ModelForm中提供讀取文件夾下文件的功能  - 參數:  path, 文件夾路徑  match = None, 正則匹配  recursive = False, 遞歸下面的文件夾  allow_files = True, 允許文件  allow_folders = False, 允許文件夾    FileField(Field)  - 字元串,路徑保存在資料庫,文件上傳到指定目錄  - 參數:  upload_to = ""  上傳文件的保存路徑  storage = None  存儲組件,默認django.core.files.storage.FileSystemStorage    ImageField(FileField)  - 字元串,路徑保存在資料庫,文件上傳到指定目錄  - 參數:  upload_to = ""  上傳文件的保存路徑  storage = None  存儲組件,默認django.core.files.storage.FileSystemStorage  width_field = None, 上傳圖片的高度保存的資料庫欄位名(字元串)  height_field = None  上傳圖片的寬度保存的資料庫欄位名(字元串)    DateTimeField(DateField)  - 日期 + 時間格式  YYYY - MM - DD  HH: MM[:ss[.uuuuuu]][TZ]    DateField(DateTimeCheckMixin, Field)  - 日期格式  YYYY - MM - DD    TimeField(DateTimeCheckMixin, Field)  - 時間格式  HH: MM[:ss[.uuuuuu]]    DurationField(Field)  - 長整數,時間間隔,資料庫中按照bigint存儲,ORM中獲取的值為datetime.timedelta類型    FloatField(Field)  - 浮點型    DecimalField(Field)  - 10  進位小數  - 參數:  max_digits,小數總長度  decimal_places,小數位長度    BinaryField(Field)  - 二進位類型

ORM欄位與資料庫實際欄位的對應關係

對應關係:      'AutoField': 'integer AUTO_INCREMENT',      'BigAutoField': 'bigint AUTO_INCREMENT',      'BinaryField': 'longblob',      'BooleanField': 'bool',      'CharField': 'varchar(%(max_length)s)',      'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',      'DateField': 'date',      'DateTimeField': 'datetime',      'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',      'DurationField': 'bigint',      'FileField': 'varchar(%(max_length)s)',      'FilePathField': 'varchar(%(max_length)s)',      'FloatField': 'double precision',      'IntegerField': 'integer',      'BigIntegerField': 'bigint',      'IPAddressField': 'char(15)',      'GenericIPAddressField': 'char(39)',      'NullBooleanField': 'bool',      'OneToOneField': 'integer',      'PositiveIntegerField': 'integer UNSIGNED',      'PositiveSmallIntegerField': 'smallint UNSIGNED',      'SlugField': 'varchar(%(max_length)s)',      'SmallIntegerField': 'smallint',      'TextField': 'longtext',      'TimeField': 'time',      'UUIDField': 'char(32)',

ORM欄位參數

null

用於表示某個欄位可以為空。

unique

如果設置 unique=True,則該欄位在此表中必須是惟一的。

db_index

如果 db_index=True, 則代表著為此欄位設置索引。

default

為該欄位設置默認值。

auto_now_add

配置 auto_now_add=True,創建數據記錄的時候會把當前時間添加到資料庫。

auto_now

配置 auto_now=True,每次更新數據記錄的時候會更新該欄位。

具體意思

null                資料庫中欄位是否可以為空  db_column           資料庫中欄位的列名  db_tablespace  default             資料庫中欄位的默認值  primary_key         資料庫中欄位是否為主鍵  db_index            資料庫中欄位是否可以建立索引  unique              資料庫中欄位是否可以建立唯一索引  unique_for_date     資料庫中欄位【日期】部分是否可以建立唯一索引  unique_for_month    資料庫中欄位【月】部分是否可以建立唯一索引  unique_for_year     資料庫中欄位【年】部分是否可以建立唯一索引    verbose_name        Admin中顯示的欄位名稱  blank               Admin中是否允許用戶輸入為空  editable            Admin中是否可以編輯  help_text           Admin中該欄位的提示資訊  choices             Admin中顯示選擇框的內容,用不變動的數據放在記憶體中從而避免跨表操作                      如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)    error_messages      自定義錯誤資訊(字典類型),從而訂製想要顯示的錯誤資訊;                      字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date                      如:{'null': "不能為空.", 'invalid': '格式錯誤'}    validators          自定義錯誤驗證(列表類型),從而訂製想要的驗證規則                      from django.core.validators import RegexValidator                      from django.core.validators import EmailValidator,URLValidator,DecimalValidator,                      MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator                      如:                          test = models.CharField(                              max_length=32,                              error_messages={                                  'c1': '優先錯資訊1',                                  'c2': '優先錯資訊2',                                  'c3': '優先錯資訊3',                              },                              validators=[                                  RegexValidator(regex='root_d+', message='錯誤了', code='c1'),                                  RegexValidator(regex='root_112233d+', message='又錯誤了', code='c2'),                                  EmailValidator(message='又錯誤了', code='c3'), ]                )

關係欄位

ForeignKey

外鍵類型在ORM中用來表示外鍵關聯關係,一般把ForeignKey欄位設置在 '一對多'中'多'的一方。ForeignKey可以和其他表做關聯關係同時也可以和自身做關聯關係。

to

設置要關聯的表

to_field

設置要關聯的表的欄位

反向查詢時,使用的欄位名,用於代替原反向查詢時的'表名_set'。

publish = ForeignKey(Blog, related_name='booklist')

db_constraint

是否在資料庫中創建外鍵約束,默認為 True。

OneToOneField

一對一欄位,通常使用一對一欄位用來擴展已有欄位。

一對一的關聯關係多用在當一張表的不同欄位查詢頻次差距過大的情況下,將本可以存儲在一張表的欄位拆開放置在兩張表中,然後將兩張表建立一對一的關聯關係。

class Author(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      age = models.IntegerField(default=18)    class AuthorDetail(models.Model):      id = models.AutoField(primary_key=True)      addr = models.CharField(max_length=32)      author = models.OneToOneField(to=Author, to_field='id')

to

設置要關聯的表

to_field

設置要關聯的欄位。

on_delete

級聯刪除選項

ManyToManyField

用於表示多對多的關聯關係。在資料庫中通過第三張表來建立關聯關係。

to

設置要關聯的表

反向查詢時,使用的欄位名,用於代替原反向查詢時的'表名_set'。

symmetrical

僅用於多對多自關聯時,指定內部是否創建反向操作的欄位。默認為 True。

class Person(models.Model):      name = models.CharField(max_length=16)      friends = models.ManyToManyField("self")

此時,person 對象沒有 person_set屬性。

class Person(models.Model):      name = models.CharField(max_length=16)      friends = models.ManyToManyField("self", symmetrical=False)

此時,person 對象可以使用 person_set 屬性進行反向查詢。

through

在使用 ManyToManyField 欄位時,Django 將自動生成一張表來管理多對多的關聯關係。但是當我們手動創建第三張表來管理多對多關係時,就需要通過 through 來指定第三張表的表名。

class Book(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      price = models.DecimalField(max_digits=5, decimal_places=2)      publish_date = models.DateField()      publish = models.ForeignKey(to='Publish', to_field='id')      authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))    class Author(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      gender = models.SmallIntegerField()      author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', on_delete=models.CASCADE)    class Book2Author(models.Model):      id = models.AutoField(primary_key=True)      book = models.ForeignKey(to=Book)      author = models.ForeignKey(to=Author)

through_field

設置要關聯的欄位:關聯欄位在Book2Author中,從這個表到Book 表,所以把 book 寫在前面。

db_table

默認創建第三張表時,設置表的名字。

多對多關聯關係的三種方式

方式一:手動創建第三張表

class Book(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      price = models.DecimalField(max_digits=5, decimal_places=2)      publish_date = models.DateField()      publish = models.ForeignKey(to='Publish', to_field='id')    class Author(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      gender = models.SmallIntegerField()      author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', on_delete=models.CASCADE)    class Book2Author(models.Model):      id = models.AutoField(primary_key=True)      book = models.ForeignKey(to=Book)      author = models.ForeignKey(to=Author)

方式二:通過 ManyToManyField 自動創建第三張表

class Book(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      price = models.DecimalField(max_digits=5, decimal_places=2)      publish_date = models.DateField()      publish = models.ForeignKey(to='Publish', to_field='id')      authors = models.ManyToManyField(to='Author')    class Author(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      gender = models.SmallIntegerField()      author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', on_delete=models.CASCADE)

方式三:設置 ManyToManyField 並指定手動創建第三張表

class Book(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      price = models.DecimalField(max_digits=5, decimal_places=2)      publish_date = models.DateField()      publish = models.ForeignKey(to='Publish', to_field='id')    class Author(models.Model):      id = models.AutoField(primary_key=True)      name = models.CharField(max_length=32)      gender = models.SmallIntegerField()      author_detail = models.OneToOneField(to='AuthorDetail', to_field='id', on_delete=models.CASCADE)    class Book2Author(models.Model):      id = models.AutoField(primary_key=True)      book = models.ForeignKey(to=Book)      author = models.ForeignKey(to=Author)

當業務需要在第三張關係表中存儲額外的欄位時,就要使用第三種方式。

這樣創建的第三張表無法使用 set、add、remove、clear方法來管理對多多關係,需要通過第三張表來進行增、刪、改,查詢一樣。

自定義欄位

class FixedCharField(models.Field):      """      自定義的char類型的欄位類      """      def __init__(self, max_length, *args, **kwargs):          self.max_length = max_length          super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)        def db_type(self, connection):          """          限定生成資料庫表的欄位類型為char,長度為max_length指定的值          """          return 'char(%s)' % self.max_length      class Class(models.Model):      id = models.AutoField(primary_key=True)      title = models.CharField(max_length=25)      # 使用自定義的char類型的欄位      cname = FixedCharField(max_length=25)

Tags: