【问题标题】:Django REST Framework: Nested Serializers not appearingDjango REST Framework:嵌套序列化程序未出现
【发布时间】:2018-05-20 01:00:47
【问题描述】:

我在使用嵌套序列化程序和 Django 休息框架时遇到问题。 将 serializer_class 设置为“UserSerializer”时,“NameSerializer”类中的嵌套数据不会出现。 但是,当我将 serializer_class 设置为“NameSerializer”时,数据确实出现了。

使用UserSerializer时API返回:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
  {
    "id": 1,
    "userName": "admin@admin.com"
  },
  {
    "id": 2,
    "userName": "2@admin.com"
  },
  {
    "id": 3,
    "userName": "3@admin.com"
  },
  {
    "id": 4,
    "userName": "4@admin.com"
  }
]

我希望它返回什么:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
  {
    "id": 1,
    "userName": "admin@admin.com"
    "name": {
      "familyName": "Joe",
      "givenName": "admin",
      "formated": "admin Joe"
    },
  },
  {
    "id": 2,
    "userName": "jane@admin.com"
    "name": {
      "familyName": "Doe",
      "givenName": "Jane",
      "formated": "Jane Doe"
    },
  },
  {
    "id": 3,
    "userName": "Billy@admin.com"
    "name": {
      "familyName": "Idol",
      "givenName": "Billy",
      "formated": "Billy Idol"
    },
  },
  {
    "id": 4,
    "userName": "User@admin.com"
    "name": {
      "familyName": "B",
      "givenName": "User",
      "formated": "User B"
    },
  }
]

views.py

from API.models import Person
from API.serializers import *
from rest_framework import viewsets

class UserViewSet(viewsets.ModelViewSet):
   queryset = Person.objects.all()
   serializer_class = NameSerializer

models.py

class Person(AbstractBaseUser):
    email = models.EmailField(
       verbose_name='email address',
       max_length=255,
       unique=True,
       )
    first_name = models.CharField(max_length=254, blank=True)
    last_name =  models.CharField(max_length=254, blank=True)

serializers.py

class NameSerializer(serializers.ModelSerializer):

  familyName = serializers.CharField(source='last_name')
  givenName = serializers.CharField(source='first_name')
  formatted = serializers.SerializerMethodField()

  class Meta:
      model = Person
      fields = ('familyName', 'givenName', 'formatted',)


  def get_formatted(slef, obj):
      FullName = obj.first_name + '' + obj.last_name
      return FullName


class UserSerializer(serializers.ModelSerializer):

  name = NameSerializer(many=True, readonly=True)
  userName = serializers.EmailField(source='email')

  class Meta:
      model = Person
      fields = ('id', 'userName', 'name')

感谢任何帮助

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    您不需要创建NameSerializer 序列化程序。在UserSerializer 中为name 字段创建一个方法字段如:

    class UserSerializer(serializers.ModelSerializer):
    
        userName = serializers.EmailField(source='email')
        name = serializers.SerializerMethodField()
    
        class Meta:
            model = Person
            fields = ('id', 'userName', 'name')
    
        def get_name(self, obj):
            name = {
                'familyName': obj.first_name,
                'givenName': obj.last_name,
                'formatted': obj.first_name + ' ' + obj.last_name
            }
            return name
    

    它会给你想要的结果。

    【讨论】:

      【解决方案2】:

      这可能会对您有所帮助:

      class UserSerializer(serializers.ModelSerializer): name = NameSerializer() userName = serializers.EmailField(source='email')

           class Meta:
               model = Person
               fields = ('id', 'userName', 'name')
      

      如果项目应该是一个列表,那么只需要传递many=True。

      【讨论】:

      • 进行上述更改时,我收到以下错误“Class UserSerializer 缺少“Meta”属性” name 在序列化器上 UserSerializer。"
      • @dev_null 这里的问题是,在您的视图查询集中,您正在从模型 Person 传递数据。在模型中,没有对 NameSerializer 的引用。
      【解决方案3】:

      也许尝试使用SerializerMethodField: 像这样的:

      class UserSerializer(serializers.ModelSerializer):
      
          userName = serializers.EmailField(source='email')
          name = serializers.SerializerMethodField()
      
          class Meta:
              model = Person
              fields = ('id', 'userName', 'name')
      
          def get_name(self, obj):
              return {
                  'familyName': obj.first_name,
                  'givenName': obj.last_name,
                  'formatted': obj.first_name + ' ' + obj.last_name
              }
      

      【讨论】:

      • 我得到了完全相同的结果。 “名称”键仍然没有出现。
      猜你喜欢
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2016-02-09
      • 2018-07-06
      • 1970-01-01
      • 2014-08-20
      • 2014-12-21
      • 1970-01-01
      相关资源
      最近更新 更多