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