一、model操作
1、創建數據庫表
一對多: def func(): return 5 class UserType(models.Model): name = models.CharField(max_length=32) class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) .... ForiegnKey(to="UserType",to_field='id',on_delete=models.SET(func)) # delete from user where id=1 # delete from UserType where id=1 # 報錯 # UserType.objects.filter(id=1).delete() # 正向操作 # v = User.objects.all() # for item in v: # item.user # item.pwd # item.ut.name # 正向跨表查詢 # User.objects.all().values('user','ut__name') # 反向操作 # v = UserType.objects.all() # for item in v: # item.name # item.id # for i in item.user_set.all() # item.b.all()
# print(i.id,i.name,i.pwd)
# 反向跨表查詢 # models.UserType.objects.all().values('name','user__pwd')
2、操作數據庫表
基本操作
# 增 # # models.Tb1.objects.create(c1='xx', c2='oo') 增加一條數據,可以接受字典類型數據 **kwargs # obj = models.Tb1(c1='xx', c2='oo') # obj.save() # 查 # # models.Tb1.objects.get(id=123) # 獲取單條數據,不存在則報錯(不建議) # models.Tb1.objects.all() # 獲取全部 # obj = models.Tb1.objects.filter(name='seven') # 獲取指定條件的數據
# obj = models.Tb1.objects.filter(name='seven').first() # 獲取指定條件的第一條數據
# count = models.Tb1.objects.filter(name='seven').count() # 計算獲取到的指定條件數據的個數
# 刪 # # models.Tb1.objects.filter(name='seven').delete() # 刪除指定條件的數據 # 改 # models.Tb1.objects.filter(name='seven').update(gender='0') # 將指定條件的數據更新,均支持 **kwargs # obj = models.Tb1.objects.get(id=1) # obj.c1 = '111' # obj.save() # 修改單條數據
3、數據驗證(弱)
full_clean進行驗證
- 執行每個字段的正則
- 執行clean鈎子函數
二、Form操作
1、數據驗證(強大)
三、ModelForm
1、數據庫操作
2、數據驗證
ModelForm耦合太強,建議操作用model,驗證用Form。
驗證流程:
ModelForm--->Form--->Model
Django之Model操作
一、字段
字段列表
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]
models.DateTimeField(auto_now_add=True) # 自動創建當前時間。 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) - 二進制類型
自定義無符號整數字段
class UnsignedIntegerField(models.IntegerField): def db_type(self, connection): return 'integer UNSIGNED' PS: 返回值為字段在數據庫中的屬性,Django字段默認的值為: '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)',
二、字段參數
null 數據庫中字段是否可以為空 db_column 數據庫中字段的列名 default 數據庫中字段的默認值 primary_key 數據庫中字段是否為主鍵 db_index 數據庫中字段是否可以建立索引 unique 數據庫中字段是否可以建立唯一索引 unique_for_date 數據庫中字段【日期】部分是否可以建立唯一索引 unique_for_month 數據庫中字段【月】部分是否可以建立唯一索引 unique_for_year 數據庫中字段【年】部分是否可以建立唯一索引
auto_now 更新時自動更新為當前時間
方法一(不更新時間)
obj = models.Userinfo.objects.filter(id=1).update(caption='CEO')
方法二(更新時間)
obj = models.Userinfo.objects.filter(id=1).first()
obj.caption = 'CEO'
obj.save()
auto_add_now 創建時自動生成時間 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_112233\d+', message='又錯誤了', code='c2'), EmailValidator(message='又錯誤了', code='c3'), ] )
三、元信息(定制數據庫表名;聯合索引;聯合唯一索引;admin中顯示的表名稱)
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) class Meta: # 數據庫中生成的表名稱 默認 app名稱 + 下划線 + 類名 db_table = "table_name" # 聯合索引 index_together = [ ("username", "pwd"), ]
# 最左前綴的模式:
# select * from where name='username'
# select * from where name='username' and email='pwd'
# select * from where email='pwd' #無法命中索引
# 聯合唯一索引 unique_together = (("driver", "restaurant"),) # admin中顯示的表名稱 verbose_name_plural # verbose_name_plural加s verbose_name
四、多表關系以及參數
ForeignKey(ForeignObject) # ForeignObject(RelatedField) to, # 要進行關聯的表名 to_field=None, # 要關聯的表中的字段名稱 on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為 - models.CASCADE,刪除被關聯數據,與之關聯(FK表的那行數據)也刪除 - models.DO_NOTHING,刪除被關聯數據,引發錯誤IntegrityError - models.PROTECT,刪除被關聯數據,引發錯誤ProtectedError - models.SET_NULL,刪除被關聯數據,與之關聯的值設置為null(前提FK字段需要設置為可空) - models.SET_DEFAULT,刪除被關聯數據,與之關聯的值設置為默認值(前提FK字段需要設置默認值) - models.SET,刪除關聯數據, a. 與之關聯的值設置為指定值,設置:models.SET(值) b. 與之關聯的值設置為可執行對象的返回值,設置:models.SET(可執行對象) def func(): return 10 class MyModel(models.Model): user = models.ForeignKey( to="User", to_field="id" on_delete=models.SET(func),) related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如:related_name=b, 反向查詢obj.表名_set.all() 就換成obj.b.all() related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件: # 如: - limit_choices_to={'nid__gt': 5} - limit_choices_to=lambda : {'nid__gt': 5} from django.db.models import Q - limit_choices_to=Q(nid__gt=10) - limit_choices_to=Q(nid=8) | Q(nid__gt=10) - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') db_constraint=True # 是否在數據庫中創建外鍵約束 parent_link=False # 在Admin中是否顯示關聯數據 OneToOneField(ForeignKey) to, # 要進行關聯的表名 to_field=None # 要關聯的表中的字段名稱 on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為 ###### 對於一對一 ###### # 1. 一對一其實就是 一對多 + 唯一索引 # 2.當兩個類之間有繼承關系時,默認會創建一個一對一字段 # 如下會在A表中額外增加一個c_ptr_id列且唯一: class C(models.Model): nid = models.AutoField(primary_key=True) part = models.CharField(max_length=12) class A(C): id = models.AutoField(primary_key=True) code = models.CharField(max_length=1) ManyToManyField(RelatedField) to, # 要進行關聯的表名 related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all() related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件: # 如: - limit_choices_to={'nid__gt': 5} - limit_choices_to=lambda : {'nid__gt': 5} from django.db.models import Q - limit_choices_to=Q(nid__gt=10) - limit_choices_to=Q(nid=8) | Q(nid__gt=10) - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') symmetrical=None, # 僅用於多對多自關聯時,symmetrical用於指定內部是否創建反向操作的字段 # 做如下操作時,不同的symmetrical會有不同的可選字段 models.BB.objects.filter(...) # 可選字段有:code, id, m1 class BB(models.Model): code = models.CharField(max_length=12) m1 = models.ManyToManyField('self',symmetrical=True) # 可選字段有: bb, code, id, m1 class BB(models.Model): code = models.CharField(max_length=12) m1 = models.ManyToManyField('self',symmetrical=False) through=None, # 自定義第三張表時,使用字段用於指定關系表 through_fields=None, # 自定義第三張表時,使用字段用於指定關系表中哪些字段做多對多關系表 # 注意:這樣定義后不能進行增刪改,但是可以通過members字段進行查、進行clear(唯一優點)
from django.db import models class Person(models.Model): name = models.CharField(max_length=50) class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField( Person, through='Membership', through_fields=('group', 'person'), ) class Membership(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) person = models.ForeignKey(Person, on_delete=models.CASCADE) inviter = models.ForeignKey( Person, on_delete=models.CASCADE, related_name="membership_invites", ) invite_reason = models.CharField(max_length=64) db_constraint=True, # 是否在數據庫中創建外鍵約束 db_table=None, # 默認創建第三張表時,數據庫中表的名稱
