最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django模型序列化返回自然主鍵值示例代碼

 更新時間:2019年06月12日 09:00:45   作者:嚴北  
這篇文章主要給大家介紹了關(guān)于Django模型序列化返回自然主鍵值的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習或者使用Django具有一定的參考學(xué)習價值,需要的朋友們下面來一起學(xué)習學(xué)習吧

場景

在設(shè)計表結(jié)構(gòu)時,難免需要建立一些外鍵關(guān)聯(lián)。例如這樣兩個模型:

from django.db import models

class Person(models.Model):
 username = models.CharField(max_length=100)
 birthdate = models.DateField()

class Book(models.Model):
 name = models.CharField(max_length=100)
 author = models.ForeignKey(Person, on_delete=models.CASCADE)

表 Book 的字段 author 是表 Person 的外鍵,我們試用 Django 原生的 Serializer 模塊來對 Book 實例序列化:

from django.core import serializers
book_json = serializers.serialize("json", Book.objects.get(pk=1))

JSON 序列化結(jié)果如下:

{
 "pk": 1,
 "model": "store.book",
 "fields": {
  "name": "Mostly Harmless",
  "author": 42
 }
}

這個 "author": 42 對用戶來說相當于未知,我們需要的是 Person 表中主鍵為 42 的用戶姓名,即 username 的值。

解決方案

在 Django 官方文檔的「序列化」一節(jié)中提到了用 models.Manager 處理的方案;在搜索解決方案過程中,也接觸到 Django-REST-Framework(DRF) ,了解到 DRF 中的 Serializer 模塊也能解決這類問題。那我們不妨對比一下兩種解決方案。

方案一:models.Manager

根據(jù)文檔,要返回自然主鍵,我們需要定義一個模型管理器,創(chuàng)建一個 get_by_natural_key 方法,如下:
from django.db import models

from django.db import models

class PersonManager(models.Manager):
 def get_by_natural_key(self, username):
  return self.get(username=username)

class Person(models.Model):
 username = models.CharField(max_length=100)
 birthdate = models.DateField()
 objects = PersonManager()

然后再次序列化 Book 實例:

from django.core import serializers
book_json = serializers.serialize("json", Book.objects.get(pk=1), use_natural_foreign_keys=True)

得到新的結(jié)果如下:

{
    "pk": 1,
    "model": "store.book",
    "fields": {
        "name": "Mostly Harmless",
        "author": ["DouglasAdams"]
    }
}

如果需要對其他應(yīng)用的數(shù)據(jù)模型做修改,例如使用了 django.auth.User(默認認證后端)作為 Book  的外鍵,要想不修改 User 模型又使用新的模型管理器,可以使用代理模式完成:

from django.db import models

class NewManager(models.Manager):
 # ...
 pass

class MyPerson(Person):
 objects = NewManager()

 class Meta:
  proxy = True

總的來說,這個方案可以完美解決我所遇到的問題,代碼量稍微大一些,但是也更靈活。

方案二:DRF 的 Serializer

下面我們試試用 Django-REST-Framework 的序列化模塊:

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
 author_name = serializers.CharField(source='author.username')

 class Meta:
  model = Book
  fields = '__all__'

這段代碼表示,在序列化 Book 實例時,添加一個新的屬性 author_name,該值的來源為 source 參數(shù)定義的外鍵 author 實例的自然主鍵 username。

然后是執(zhí)行序列化的過程:

queryset = Book.objects.get(pk=1)
BookSerializer(instance=queryset)

序列化結(jié)果:

{
    "id": 1,
    "name": "Mostly Harmless",
    "author": 42,
    "author_name": "DouglasAdams"
}

當然,序列化一批 Book 實例也是可以的:

queryset = Book.objects.all()
BookSerializer(instance=queryset, many=True)

序列化結(jié)果:

[
    {
        "id": 1,
        "name": "Mostly Harmless",
        "author": 42,
        "author_name": "DouglasAdams"
    },
    {
        "id": 2,
        "name": "Harry Potter",
        "author": 2,
        "author_name": "JKRowling"
    }
]

可以看到,使用 DRF 的序列化模塊返回自然主鍵,不僅代碼清晰改動少,而且效果也很不錯,序列化數(shù)據(jù)少了一個層級,對前端也是十分友好的。

方案三:手動修改序列化后的外鍵

當然,還有一種最傻也是最容易想到的辦法,就是在序列化后,手動修改 JSON 串中對應(yīng)的外鍵值為自然主鍵值。

這種做法可以得到和方案一一樣的效果,但是遇到查詢結(jié)果為列表時我們需要遍歷替換。同時試想一下,如果我們在每個視圖中都這么處理,那代碼會變得十分糟糕。不建議使用該方案。

總結(jié)

對比兩種序列化方案,我個人更偏向于 DRF 優(yōu)雅的處理方式。當然,除了序列化,DRF 還有很多功能,例如分頁等,強烈建議學(xué)習學(xué)習。

當然,可能不存在最好的最好的技術(shù)方案,遇到這類問題選擇最合適自己的就好。也可能還有更多的方法可以解決標題的問題,也歡迎留言探討!

參考

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Python計算當前日期是一年中的第幾天的方法詳解

    Python計算當前日期是一年中的第幾天的方法詳解

    在Python中,計算當前日期是一年中的第幾天可以通過內(nèi)置的datetime模塊來實現(xiàn),本文將詳細介紹如何使用Python編寫代碼來完成這個任務(wù),需要的可以參考下
    2023-12-12
  • Python 鍵盤事件詳解

    Python 鍵盤事件詳解

    這篇文章主要為大家詳細介紹了Python的 鍵盤事件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • python3實現(xiàn)字符串操作的實例代碼

    python3實現(xiàn)字符串操作的實例代碼

    這篇文章主要介紹了python3實現(xiàn)字符串操作的實例代碼,需要的朋友可以參考下
    2019-04-04
  • Python3使用tesserocr識別字母數(shù)字驗證碼的實現(xiàn)

    Python3使用tesserocr識別字母數(shù)字驗證碼的實現(xiàn)

    這篇文章主要介紹了Python3使用tesserocr識別字母數(shù)字驗證碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2021-01-01
  • python實現(xiàn)對變位詞的判斷方法

    python實現(xiàn)對變位詞的判斷方法

    這篇文章主要為大家詳細介紹了python實現(xiàn)對變位詞的判斷方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • pytorch 簡介及常用工具包展示

    pytorch 簡介及常用工具包展示

    Pytorch是torch的python版本,是由Facebook開源的神經(jīng)網(wǎng)絡(luò)框架,專門針對 GPU 加速的深度神經(jīng)網(wǎng)絡(luò)(DNN)編程,這篇文章主要介紹了pytorch 簡介及常用工具包展示,需要的朋友可以參考下
    2023-02-02
  • python發(fā)送多人郵件沒有展示收件人問題的解決方法

    python發(fā)送多人郵件沒有展示收件人問題的解決方法

    這篇文章主要為大家詳細介紹了python發(fā)送多人郵件沒有展示收件人問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • python實現(xiàn)簡單的socket server實例

    python實現(xiàn)簡單的socket server實例

    這篇文章主要介紹了python實現(xiàn)簡單的socket server的方法,實例分析了Python中socket的操作技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • Python基于ssh遠程連接Mysql數(shù)據(jù)庫操作

    Python基于ssh遠程連接Mysql數(shù)據(jù)庫操作

    這篇文章主要為大家介紹了Python基于ssh遠程連接Mysql數(shù)據(jù)庫操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 在matplotlib中改變figure的布局和大小實例

    在matplotlib中改變figure的布局和大小實例

    這篇文章主要介紹了在matplotlib中改變figure的布局和大小實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04

最新評論

布拖县| 贵南县| 裕民县| 微山县| 阜平县| 彭州市| 临洮县| 定兴县| 淮南市| 烟台市| 华阴市| 卓尼县| 滨州市| 通榆县| 那坡县| 康定县| 稻城县| 宁河县| 长宁县| 乐清市| 德阳市| 繁峙县| 双桥区| 集贤县| 定结县| 江西省| 子长县| 苏尼特右旗| 页游| 临武县| 合川市| 陇西县| 图们市| 沛县| 南城县| 钦州市| 曲麻莱县| 中方县| 东乡族自治县| 安义县| 东宁县|