1. 程式人生 > >6.連表結構

6.連表結構

多選 關聯 tab urn protected 額外 lte 微軟雅黑 多個

一、三種結構及應用場景

一對多:models.ForeignKey(其他表)

多對多:models.ManyToManyField(其他表)

一對一:models.OneToOneField(其他表)

應用場景:

一對多:當一張表中創建一行數據時,有一個單選的下拉框(可以被重復選擇)

例如:創建用戶信息時候,需要選擇一個用戶類型【普通用戶】【金牌用戶】【鉑金用戶】等。

多對多:在某表中創建一行數據是,有一個可以多選的下拉框

例如:創建用戶信息,需要為用戶指定多個愛好

一對一:在某表中創建一行數據時,有一個單選的下拉框(下拉框中的內容被用過一次就消失了

例如:原有含10列數據的一張表保存相關信息,經過一段時間之後,

10列無法滿足需求,需要為原來的表再添加5列數據

二、連表時常用參數

1ForeignKey

ForeignKey(ForeignObject) # ForeignObject(RelatedField)

to, # 要進行關聯的表名

to_field=None, # 要關聯的表中的字段名稱

on_delete=None, # 當刪除關聯表中的數據時,當前表與其關聯的行的行為

- models.CASCADE,刪除關聯數據,與之關聯也刪除

- 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】 如: obj.表名_set.all()

related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘)

limit_choices_to=None, # AdminModelForm中顯示關聯數據時,提供的條件:

# 如:

- 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中是否顯示關聯數據

2OneToOneField

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)

3ManyToManyField

ManyToManyField(RelatedField)

to, # 要進行關聯的表名

related_name=None, # 反向操作時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all()

related_query_name=None, # 反向操作時,使用的連接前綴,用於替換【表名】如: models.UserGroup.objects.filter(表名__字段名=1).values(‘表名__字段名‘)

limit_choices_to=None, # AdminModelForm中顯示關聯數據時,提供的條件:

# 如:

- 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, # 自定義第三張表時,使用字段用於指定關系表中那些字段做多對多關系表

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, # 默認創建第三張表時,數據庫中表的名稱

6.連表結構