1.索引:
普通索引:加快查找速度
唯一索引:加快查找速度,唯一約束
主鍵索引:加快查找速度,唯一索引,不為空
class UserInfo(models.Model): username = models.CharField( null=False, #不允許為空 db_column='user', #自定義列名,可以修改再數據庫中的列名 max_length=32, db_index=True, #普通索引,只能加速查找 # unique=True, #約束索引,加速查找,唯一約束 # primary=True, #主鍵索引,加速查找,唯一約束,不為空 )
gender = models.BooleanField( default=True #設置默認值 )
元類使用:
用於生成聯合索引,以及設置個別參數
#元類信息 class Meta: # 數據庫中生成的表名稱 默認 app名稱 + 下划線 + 類名 db_table = "app01_un" # 聯合索引 # index_together = [ # ("username", "gender"), # ] # 聯合唯一索引 unique_together = (("username", "gender"),) #IntegrityError: columns user, gender are not unique # admin中顯示的表名稱 verbose_name = "用戶信息"
2.一對多外鍵建立:
el = models.ForeignKey( to="EmailInfo", #關聯表 to_field='id', #關聯列名
db_constraint=True #是否在數據庫該表中創建外鍵約束(外鍵功能查找等依舊存在,但是不具有約束功能) 比如:有約束時,郵箱id1-10,那么在該表中el也會是1-10,但是當false時,該el設置可以是任意,不受關聯表的約束
limit_choices_to=None, #在Admin或者ModelForm中顯示數據時,提供限制后的數據展示
--limit_choices_to={'id_gt':5}
--limit_choices_to=lambda:{'id_gt':5}#或者lambda表達式 )

class EmailInfo(models.Model): email = models.EmailField( null=False, db_index=True, unique=True, )
添加信息:
#添加信息 UserInfo.objects.create( username="張三", gender=True, el_id=1 ) UserInfo.objects.create( username="李四", gender=True, el_id=2 )
#因為唯一約束,是對姓名,性別一起約束,所以當不同時,是可以進行添加的 UserInfo.objects.create( username="王五", gender=False, el_id=3 ) UserInfo.objects.create( username="王五", gender=True, el_id=3 ) UserInfo.objects.create( username="趙六", gender=True, el_id=4 ) EmailInfo.objects.create(**{'email': '46412454@qq.com'}) EmailInfo.objects.create(**{'email': '4641245454@qq.com'}) EmailInfo.objects.create(**{'email': '46412fwa454@qq.com'})
對於外鍵,刪除是是默認為級聯刪除,當刪除一個,對應相關數據也會被刪除,所以,我們有時候需要修改這一性質,在創建外鍵是使用on_delete即可
對於on_delete的幾種設置:
def set_test(): return 4
el = models.ForeignKey( to="EmailInfo", #關聯表 to_field='id', #關聯列名 null=True, default=2, #刪除自己數據,對於被關聯方,一點影響都沒有 #on_delete=None, #當關聯的email數據被刪除時候,該數據也會被刪除,不存在 #on_delete=models.CASCADE, #性質和None一樣是默認刪除
#on_delete=models.DO_NOTHING, #當關聯的數據被刪除時,自己不受影響,什么事都不做,不會報錯
#on_delete=models.PROTECT, #關聯保護,因為郵箱數據被用戶表關聯,所以該郵箱不允許被刪除,並且觸發ProtectError #Cannot delete some instances of model 'EmailInfo' because they are referenced through a protected foreign key: 'UserInfo.el'", <QuerySet [<UserInfo: UserInfo object>]>
#on_delete=models.SET_NULL, #刪除關聯數據,自己被設置為null(前提字段需要設置為可空null=True) #對於測試models.SET_NULL時,我們需要先了解,對於數據庫的基本字段設置,像null,max_length這些屬性,我們需要重新去生成數據表, #對於on_delete等Django中的附屬屬性,我們可以動態修改,不需要重新生成數據表,所以如果我們開始並沒有設置null=True(默認false),我們需要去重新生成數據表 #on_delete=models.SET_DEFAULT,#刪除關聯數據后,會將自己的數據設置為默認值,需要設置default屬性
#on_delete=models.SET(3) #和SET_DEFAULT相似,只不過不需要設置默認值,在SET()中可以直接設置 on_delete=models.SET(set_test) #和SET一樣,只不過值設為了回調函數,需要將函數設為全局,可調用 )
3.一對一:與一對多外鍵屬性幾乎一致,只是在unique上多加了true。兩種實現:o和o1
class User(models.Model): username = models.CharField( max_length=32, db_index=True, ) class Tag(models.Model): title = models.CharField( max_length=16, ) o = models.OneToOneField( to='User', to_field='id', on_delete=None, ###### 對於一對一 ###### # 1. 一對一其實就是 一對多 + 唯一索引 # 2.當兩個類之間有繼承關系時,默認會創建一個一對一字段 # 如下會在A表中額外增加一個c_ptr_id列且唯一: ) o1 = models.ForeignKey( to='User', to_field='id', on_delete=None, unique=True, )
4.多對多ManyToManyField
class User(models.Model): username = models.CharField( max_length=32, db_index=True, ) def __str__(self): return self.username class Tag(models.Model): title = models.CharField( max_length=16, ) # m = models.ManyToManyField(to="User") # 使用ManyToManyField只能在第三張表中創建3列數據id(主鍵自增),外鍵1_id,外鍵2_id # m = models.ManyToManyField( # to="User", # related_name="tag", #反向查詢是設置的字段名,替換(表名_set)默認是表名_set,這里設置后就可以簡化了 # related_query_name="tg", #反向查詢是用於替換(表名) # limit_choices_to=None, #在admin中或者modelform中進行限制字段 # db_constraint=True #同外鍵約束一致 # ) def __str__(self): return self.title
自定義第三張表(查詢方便):
#自定義第三張表 class UserToTag(models.Model): nid = models.AutoField( primary_key=True ) u = models.ForeignKey(to="User") t = models.ForeignKey(to="Tag") ctime = models.DateField() #ManyToManyField中含有聯合唯一 class Meta: #聯合唯一 unique_together=[ ('u', 't'), ]
補充:through,through_fields.
django除了能自動創建多對多的第三張表,同樣也可以自定義創建多對多的第三張表,而且操作和管理擴展等難易程度要比自動創建的好許多。所以,在之后的models表結構中,推薦使用自定義的方式。並且加上through和through_fields
class User(models.Model): username = models.CharField( max_length=32, db_index=True )class Tag(models.Model): title = models.CharField( max_length=32, db_index=True, ) members = models.ManyToManyField( User, through='UserToTag', through_fields=('u','t'), ) class UserToTag(models.Model): u = models.ForeignKey( User, on_delete=models.CASCADE ) t = models.ForeignKey( Tag, on_delete=models.CASCADE )
操作:
models.UserToTag.objects.create( u=models.User.objects.get(id=1), t=models.Tag.objects.get(id=2) )
其他添加方法看:python---django中orm的使用(1)
5.多對多---自查詢:
class User(models.Model): username = models.CharField( max_length=32, db_index=True ) # 自關聯(互粉操作),反向操作容易亂(各個表對他的反向操作都是User_set),最好加上related_name,以后最好都加上related_name # d = models.ManyToManyField("User",related_name='b')