# 半夜擼代碼 正在一頓操作猛如虎的時候,發現刪了其中一張表的某條記錄,結果發現其他表跟這個字段的關聯的也都被刪除,我已經寫了db_constraint=False 難道我用錯了,最后只能查資料,原來想斷關聯還想連表查詢做這個是不夠的,還需要null=True, blank=True,on_delete=models.SET_NUL這里我之前寫的是on_delete=models.CASCADE 默認級聯刪除,坑了自己一把,還有昨天晚上也是,后台寫好,萬事具備的時候,准備開擼前台,ajax請求就是不通,各種改地址 端口,最后居然是配置里'corsheaders.middleware.CorsMiddleware'這個沒加,唉,擼個代碼配環境還要配幾個小時?
1.設置為null
class BookModel(models.Model):
"""
圖書
"""
book_name = models.CharField(max_length=100, verbose_name='書名')
# 表示外鍵關聯到作者表,當作者表刪除了該條數據,圖書表中不刪除,僅僅是把外鍵置空
author = models.ForeignKey(AuthModel, null=True, blank=True, on_delete=models.SET_NULL)
price = models.FloatField(verbose_name='價格')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='添加時間')
2.建表時其他參數的設置
CASCADE:這就是默認的選項,級聯刪除,你無需顯性指定它。
PROTECT: 保護模式,如果采用該選項,刪除的時候,會拋出ProtectedError錯誤。
SET_NULL: 置空模式,刪除的時候,外鍵字段被設置為空,前提就是blank=True, null=True,定義該字段的時候,允許為空。
SET_DEFAULT: 置默認值,刪除的時候,外鍵字段設置為默認值,所以定義外鍵的時候注意加上一個默認值。
SET(): 自定義一個值,該值當然只能是對應的實體了
3.set的使用
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user),
)
4.ManyToMany參數(through,db_constraint)
class Book(models.Model):
name=models.CharField(max_length=20)
authors=models.ManyToMany('Author',through='Score')
class Author(models.Model):
name=models.CharField(max_length=20)
class Score(models.Model):
book=models.ForeignKey('Book')
author=models.ForeignKey('Author')
socre=models.IntegerField()
#######
如果只寫manytomany,那么第三張是Django替我們建的,可以通過book.authors字段進行一系列操作(add(增),all(查),set(重置),remove(刪除)),但是此時沒法給第三張表加其他我們需要的字段,
而如果不寫,ManyToMany字段,那么我們可以通過Score來執行一些操作,但是此時book和author表已經沒有直接的聯系了,查詢起來很繁瑣
有了authors=models.ManyToMany('Author',through='Score'),那么就既可以方便查,也方便業務,添加需要的字段
5.db_constraint
db_constraint=False,這個就是保留跨表查詢的便利(雙下划線跨表查詢```),但是不用約束字段了,一般公司都用false,這樣就省的報錯,因為沒有了約束(Field字段對象,既約束,又建立表與表之間的關系)
limit_choices_to
限制關聯字段的對象范圍
related_name
反向查詢字段可以不用 表名小寫,可以改名了
db_table
第三張表的名字
models.ForeignKey(AuthModel, null=True, blank=True, on_delete=models.SET_NULL,db_constraint=False)
5.總結
如果使用兩個表之間存在關聯,首先db_constraint=False 把關聯切斷,但保留連表查詢的功能,其次要設置null=True, blank=True,注意on_delete=models.SET_NULL 一定要置空,這樣刪了不會影響其他關聯的表