欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

場(chǎng)景

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

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 的外鍵,我們?cè)囉?Django 原生的 Serializer 模塊來(lái)對(duì) Book 實(shí)例序列化:

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
 }
}

這個(gè) "author": 42 對(duì)用戶來(lái)說(shuō)相當(dāng)于未知,我們需要的是 Person 表中主鍵為 42 的用戶姓名,即 username 的值。

解決方案

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

方案一:models.Manager

根據(jù)文檔,要返回自然主鍵,我們需要定義一個(gè)模型管理器,創(chuàng)建一個(gè) 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 實(shí)例:

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"]
    }
}

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

from django.db import models

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

class MyPerson(Person):
 objects = NewManager()

 class Meta:
  proxy = True

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

方案二:DRF 的 Serializer

下面我們?cè)囋囉?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 實(shí)例時(shí),添加一個(gè)新的屬性 author_name,該值的來(lái)源為 source 參數(shù)定義的外鍵 author 實(shí)例的自然主鍵 username。

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

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

序列化結(jié)果:

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

當(dāng)然,序列化一批 Book 實(shí)例也是可以的:

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 的序列化模塊返回自然主鍵,不僅代碼清晰改動(dòng)少,而且效果也很不錯(cuò),序列化數(shù)據(jù)少了一個(gè)層級(jí),對(duì)前端也是十分友好的。

方案三:手動(dòng)修改序列化后的外鍵

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

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

總結(jié)

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

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

參考

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

相關(guān)文章

  • python腳本實(shí)現(xiàn)驗(yàn)證碼識(shí)別

    python腳本實(shí)現(xiàn)驗(yàn)證碼識(shí)別

    這篇文章主要為大家詳細(xì)介紹了python腳本實(shí)現(xiàn)驗(yàn)證碼識(shí)別的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • python實(shí)現(xiàn)redis三種cas事務(wù)操作

    python實(shí)現(xiàn)redis三種cas事務(wù)操作

    本篇文章主要介紹了python實(shí)現(xiàn)redis三種cas事務(wù)操作,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • sklearn線性邏輯回歸和非線性邏輯回歸的實(shí)現(xiàn)

    sklearn線性邏輯回歸和非線性邏輯回歸的實(shí)現(xiàn)

    這篇文章主要介紹了sklearn線性邏輯回歸和非線性邏輯回歸的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • python3.5 tkinter實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)

    python3.5 tkinter實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了python3.5 tkinter實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 菜鳥使用python實(shí)現(xiàn)正則檢測(cè)密碼合法性

    菜鳥使用python實(shí)現(xiàn)正則檢測(cè)密碼合法性

    本文給大家分享了2則使用Python實(shí)現(xiàn)正則表達(dá)式檢測(cè)密碼合法性的代碼,由于是新手,所以方法比較笨,不過(guò)還是分享給小伙伴,希望對(duì)大家能夠有所幫助。
    2016-01-01
  • 一文搞懂Python中列表List和元組Tuple的使用

    一文搞懂Python中列表List和元組Tuple的使用

    列表List 和 元組Tuple 可以說(shuō)是 Python 中最通用、最有用的數(shù)據(jù)類型。列表是動(dòng)態(tài)的,而元組具有靜態(tài)特征。本文將通過(guò)示例詳細(xì)講解二者的使用方法,需要的可以參考一下
    2022-04-04
  • Django視圖類型總結(jié)

    Django視圖類型總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于Django視圖類型的總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • Python搭建代理IP池實(shí)現(xiàn)檢測(cè)IP的方法

    Python搭建代理IP池實(shí)現(xiàn)檢測(cè)IP的方法

    這篇文章主要介紹了Python搭建代理IP池實(shí)現(xiàn)檢測(cè)IP的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 如何修改pycharm使用anaconda環(huán)境后的pip install安裝路徑問題

    如何修改pycharm使用anaconda環(huán)境后的pip install安裝路徑問題

    本文主要介紹了如何修改pycharm使用anaconda環(huán)境后的pip install安裝路徑問題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器的方法

    使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器的方法

    這篇文章主要介紹了使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器 的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07

最新評(píng)論