drf-外鍵字段設置及子序列化


基表

  • 基表只提供公有字段, 不參與數據庫遷移
  • 在基表下的配置類class Meta:中設置: abstract = True, 表明該表為抽象表, 不參與數據庫遷移
Copy# 基表
class Base(models.Model):  
    is_delete = models.BooleanField(default=False)
    created_time = models.DateTimeField(auto_now=True)
    
    class Meta:
        # 表明該表為抽象表, 只提供公有字段, 不參與數據庫遷移 
        abstract = True

外鍵字段參數

db_constraint 數據庫關聯#

  • 斷關聯: db_constraint=False, 既數據庫中不會建立外鍵關系, Django在代碼層面上實現兩表關聯
  • 優點
    • 不會影響連表查詢操作效率
    • 可以提升連表增刪改效率
    • 易於后期數據庫表的重構
  • 缺點
    • 數據庫本身沒有連表檢測, 容易出現臟數據 (需要通過嚴格的邏輯避免, 必要時管理臟數據)
Copyclass Book(Base):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    press = models.ForeignKey(to='Press', related_name='books', db_constraint=False, on_delete=models.SET_NULL, null=True)
    authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)


class Press(Base):
    name = models.CharField(max_length=64)
    addr = models.CharField(max_length=64)


class Author(Base):
    name = models.CharField(max_length=64)
    # 邏輯不合理
    # author_detail = models.OneToOneField(to='AuthorDetail')


class AuthorDetail(Base):
    mobile = models.CharField(max_length=64)
    author = models.OneToOneField(to=Author, related_name='detail', db_constraint=False, on_delete=models.CASCADE)
Copy"""
在外鍵字段中設置related_name: 
1.為反向查詢的輔助字段名(正向查詢按字段屬性, 反向查詢按related_name)
2.related_name可以作為字段名參加序列化類中的fields設置
"""

on_delete 級聯關系#

Copy"""
A表依賴B表, b記錄刪除,
    on_delete=models.CASCADE                    a記錄也會被刪除
    on_delete=models.DO_NOTHING                 a記錄對應外鍵字段不受影響
    on_delete=models.SET_DEFAULT, default=1     a記錄對應外鍵字段變為默認值
    on_delete=models.SET_NULL, null=True        a記錄對應外鍵字段變為null
    注:多對多外鍵字段不能修改級聯關系, 默認是 on_delete=models.CASCADE
"""

子序列化

  • 只能在序列化類中使用
  • 子序列化的字段名必須是外鍵字段(正向反向都可以, 包括related_name)
  • 子序列化字段關聯多條數據時, 需要明確 many=True
  • 子序列化是單向的, 原因很簡單, 一個位置在上, 一個位置在下
Copyclass BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['name']


class PressModelSerializer(serializers.ModelSerializer):
    # 子序列化字段
    books = BookMethodSerializer(many=True)

    class Meta:
        model = models.Press
        fields = ['name', 'addr', 'books']
Copy# 使用子序列化的返回結果
{
    "status": 0,
    "msg": "ok",
    "result": [
        {
            "name": "東方出版社",
            "addr": "上海",
            "books": [
                {
                    "name": "三體"
                },
                {
                    "name": "球狀閃電"
                }
            ]
        },
        {
            "name": "北方出版社",
            "addr": "北京",
            "books": [
                {
                    "name": "今日簡史"
                }
            ]
        }
    ]
}


-----------------------------------------------------------------------------------------------------


# 未使用子序列化的返回結果
{
    "status": 0,
    "msg": "ok",
    "result": [
        {
            "name": "東方出版社",
            "addr": "上海",
            "books": [
                1,
                3
            ]
        },
        {
            "name": "北方出版社",
            "addr": "北京",
            "books": [
                2
            ]
        }
    ]
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM