Django Rest Framework序列化外鍵相關的案例


01-序列化外鍵,獲取外鍵id以外的值

# model.py

# -*- encoding: utf-8 -*-
from django.db import models


# Create your models here.

# 字典類型表
class dicttype(models.Model):
    dic_type = models.CharField(max_length=20, verbose_name=u'字典類型')
    dic_mode = models.CharField(max_length=20, verbose_name=u'所屬模塊', null=True, blank=True)

    class Meta:
        verbose_name = u'字典類別表'
        verbose_name_plural = verbose_name  # Django表單復數信息
        db_table = 'uni_dicttype'  # 指定生成數據庫的表名稱

    def __unicode__(self):
        return self.dic_type

    def __str__(self):
        return self.dic_type


# 字典表
class dictdocument(models.Model):
    dic_name = models.CharField(max_length=20, verbose_name=u'字典項')
    dic_string = models.CharField(max_length=20, verbose_name=u'標識符')
    dic_type = models.ForeignKey(dicttype, null=True, blank=True, verbose_name=u'設備類型')

    class Meta:
        verbose_name = u'字典'
        verbose_name_plural = verbose_name
        db_table = 'uni_dictdocument'

    def __unicode__(self):
        return self.dic_name

    def __str__(self):
        return self.dic_name

需求:

  在序列化字典表的dic_type字段時,只會獲取到 dic_type_id,所以 需要將 字典表外鍵關聯的 字典類型表(dicttype) 的 dic_type 字段 進行序列化!

01-解決方法1:

  在序列化的時候創建一個新的字段(dic_type_dt)並且在這個字段中指定 source= 這個屬性,具體操作如下:

# dictdocument_serializers.py

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from apps.docpedia.models_dic import dictdocument


class DictdocumentSerialiser(ModelSerializer):
    # source='dic_type.dic_type' 的第一個dic_type是字典表的dic_type字段,第二個dic_type是 字典類型表的dic_type字段
    dic_type_dt = serializers.CharField(source='dic_type.dic_type')
    # dic_type_id = serializers.IntegerField()

    class Meta:
        model = dictdocument
        fields = ('dic_name', 'dic_string', 'dic_type', 'dic_type_dt',)

第二個字段dic_type_id之所以沒有添加source=這個屬性,是因為這個字段名跟model中的字段名一樣,django會自動識別,如果把這個字段換為questionnaire_ID那么就需要設置source=這個屬性。

 

02-解決方法2:

  直接在model中通過 @property裝飾器 創建一個名為questionnaire_title的函數,並在函數中返回我們想要拿到的信息如:dic_type.dic_type,然后在序列化時指定為ReadOnlyField()字段;具體操作如下:

# model.py

# -*- encoding: utf-8 -*-
from django.db import models


# Create your models here.

# 字典類型表
class dicttype(models.Model):
    dic_type = models.CharField(max_length=20, verbose_name=u'字典類型')
    dic_mode = models.CharField(max_length=20, verbose_name=u'所屬模塊', null=True, blank=True)

    class Meta:
        verbose_name = u'字典類別表'
        verbose_name_plural = verbose_name  # Django表單復數信息
        db_table = 'uni_dicttype'  # 指定生成數據庫的表名稱

# 字典表
class dictdocument(models.Model):
    dic_name = models.CharField(max_length=20, verbose_name=u'字典項')
    dic_string = models.CharField(max_length=20, verbose_name=u'標識符')
    dic_type = models.ForeignKey(dicttype, null=True, blank=True, verbose_name=u'設備類型')

    class Meta:
        verbose_name = u'字典'
        verbose_name_plural = verbose_name
        db_table = 'uni_dictdocument'

    @property
    def dic_type_dt(self):
        return self.dic_type.dic_type

 

# dictdocument_serializers.py

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from apps.docpedia.models_dic import dictdocument


class DictdocumentSerialiser(ModelSerializer):
    # source='dic_type.dic_type' 的第一個dic_type是字典表的dic_type字段,第二個dic_type是 字典類型表的dic_type字段
    dic_type_dt = serializers.ReadOnlyField()
    dic_type_id = serializers.ReadOnlyField()

    class Meta:
        model = dictdocument
        fields = ('dic_name', 'dic_string', 'dic_type', 'dic_type_dt', 'dic_type_id')

 

注意:這兩種解決方法所獲取到的 外鍵id以外的值,不能在地址欄 進行過濾 篩選操作。

如:http://127.0.0.1:8000/api/uni_docpedias/?doc_dev_name=變壓器

 參考文檔:https://blog.csdn.net/WanYu_Lss/article/details/82120259

02-外鍵關聯的反查詢操作

# model.py

# -*- encoding: utf-8 -*-
from django.db import models


# Create your models here.

# 字典類型表
class dicttype(models.Model):
    dic_type = models.CharField(max_length=20, verbose_name=u'字典類型')
    dic_mode = models.CharField(max_length=20, verbose_name=u'所屬模塊', null=True, blank=True)

    class Meta:
        verbose_name = u'字典類別表'
        verbose_name_plural = verbose_name  # Django表單復數信息
        db_table = 'uni_dicttype'  # 指定生成數據庫的表名稱

# 字典表
class dictdocument(models.Model):
    dic_name = models.CharField(max_length=20, verbose_name=u'字典項')
    dic_string = models.CharField(max_length=20, verbose_name=u'標識符')
    dic_type = models.ForeignKey(dicttype, null=True, blank=True, verbose_name=u'設備類型')

    class Meta:
        verbose_name = u'字典'
        verbose_name_plural = verbose_name
        db_table = 'uni_dictdocument'

需求:

  要查詢 字典類型 下的所有 設備類型!

解決方法:

  外鍵關聯的時候要在帶 ForeignKey的字段里, 設置related_name='名字',如果不設置,那么在使用的時候,serializers.py的時候,應該使用  表名_set  的字段,所以想到得到目標結果,應該這么寫:

# dict_type_serializers.py

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from apps.docpedia.models_dic import dicttype


class DicttypeSerialiser(ModelSerializer):
    dictdocument_set = serializers.StringRelatedField(many=True)

    class Meta:
        model = dicttype
        fields = ('id', 'dic_type', 'dic_mode', 'dictdocument_set')

 

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 2,
            "dic_type": "CKYY",
            "dic_mode": "出庫信息表",
            "dictdocument_set": [
                "設備替換"
            ]
        },
        {
            "id": 1,
            "dic_type": "transformer",
            "dic_mode": "",
            "dictdocument_set": [
                "干式",
                "濕式",
                "柴油",
                "交流",
                "直流"
            ]
        }
    ]
}
查詢結果

 參考文檔:https://blog.csdn.net/xiaotao745324325/article/details/51778377

 官方文檔:http://www.django-rest-framework.org/api-guide/relations/ 

 


免責聲明!

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



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