drf中表之間斷關聯操做

斷關聯表關係有優勢也有缺點,先看代碼:
from django.db import models

# Book表:
# Publish表:
# Author表:
# AuthorDetail表:
from django.contrib.auth.models import User
class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    created_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 基表,爲抽象表,是專門用來被繼承,提供公有字段的,自身不會完成數據庫遷移
        abstract = True


# 斷關聯表關係
# 1)不會影響連表查詢操做效率
# 2)會提高連表增刪改操做效率
# 3)易於後期數據庫表的重構
# 4)缺點在於:數據庫自己沒有連表檢測,容易出現髒數據,須要經過嚴格的邏輯避免髒數據的參數(必要的時候管理髒數據)

# 舉例:A依賴B,先插入A記錄,該記錄對應的B記錄沒產生,在沒有關聯的狀況下,該操做能夠實現,可是數據就是髒數據
# 接着再將B數據添加,髒數據就獲得處理了。反過來先操做B後操做A,更知足邏輯思惟,同樣能夠執行。經過邏輯將AB表進行
# 連表查詢,不會有任何異常

"""
表關係
1)Book 和 Publish 一對多:外鍵在多的一方 Book
2)Book 和 Author 多對多:外鍵在查詢頻率高的一方 Book
3)Author 和 AuthorDetail 一對一:外鍵要根據實際需求創建在合理的位置 AuthorDetail
"""
""" 外鍵字段屬性
1)related_name在外鍵中設置外鍵反向查詢的字段名:正向找字段名,反向找related_name值
2)on_delete在外鍵中必須設置,表示級聯關係,在Django 1.x下,系統默認提供(值爲models.CASCADE),Django 2.x下,必須手動明確
        CASCADE:默認值,級聯
            例子:做者沒,詳情必定沒,存在沒意義
        DO_NOTHING:外鍵不會被級聯,假設A表依賴B表,B記錄刪除,A表的外鍵字段不作任何處理
            例子:做者沒,書仍是做者寫的 | 出版社沒,書仍是該出版社出版的
        SET_DEFAULT:假設A表依賴B表,B記錄刪除,A表的外鍵字段置爲default屬性設置的值,因此必須配合default屬性使用
            例子:部門沒,部門員工進入待定部門(注:部門表必定要有待定部門記錄)
        SET_NULL:假設A表依賴B表,B記錄刪除,A表的外鍵字段置爲null,因此必須配合null=True屬性使用
            例子:部門沒,部門員工進入未分組部門(注:關聯部門表外鍵能夠爲空)
        
        注:多對多字段不能設置on_delete級聯關係,默認爲級聯,若是要處理級聯關係,須要手動明確關係表,處理關係表中的多個外鍵
        
3) db_constraint在外鍵中控制表關聯,默認爲True表示關聯,設置False表示斷開關聯
"""
class Book(BaseModel):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING, null=True)
    authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)

    def __str__(self):
        return self.name

class Publish(BaseModel):
    name = models.CharField(max_length=64)
    address = models.CharField(max_length=64)

class Author(BaseModel):
    name = models.CharField(max_length=64)

class AuthorDetail(BaseModel):
    mobile = models.CharField(max_length=64)
    author = models.OneToOneField(to=Author, related_name='detail', db_constraint=False, on_delete=models.CASCADE)

子序列

  • 只能在序列化中使用
  • 字段名必須是外鍵(正向反向)字段
  • 由於相對於自定義序列化外鍵字段,自定義序列化字段是不能參與反序列化的,而子序列化必須爲外鍵名,因此就沒法入庫
  • 在外鍵關聯數據是多條時,須要明確many=True
  • 是單向操做,由於做爲子序列化的類必須寫在上方,因此不能產生逆方向的子序列化
# 出版社羣查
class PublishAPIView(APIView):
    def get(self, request, *args, **kwargs):
        publish_query = models.Publish.objects.all()
        publish_ser = serializers.PublishModelSerializer(publish_query, many=True)
        return Response({
            'status': 0,
            'msg': 'ok',
            'results': publish_ser.data
        })
class PublishModelSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = models.Publish
        # fields = '__all__'
        fields = ['name', 'address', 'books']
相關文章
相關標籤/搜索