【问题标题】:How to override the create method for a nested serializer for an APIView post request method?如何覆盖 APIView 发布请求方法的嵌套序列化程序的创建方法?
【发布时间】:2022-02-02 01:42:35
【问题描述】:

我正在尝试覆盖以下序列化程序的 create() 方法:

serializers.py

class TaggingSerializer(serializers.ModelSerializer):
  tag = TagSerializer()
  resource = ResourceSerializer()
  gameround = GameroundSerializer()
  user = CustomUserSerializer(required=False)

  class Meta:
    model = Tagging
    fields = ('id', 'user', 'gameround', 'resource', 'tag', 'created', 'score', 'origin')

  def create(self, validated_data):
    """Create and return a new tagging"""

    tags_data = validated_data.pop('tags')
    resources_data = validated_data.pop('resources')
    gamerounds_data = validated_data.pop('gamerounds')
    users_data = validated_data.pop('users')
    tagging = Tagging.objects.create(**validated_data)

    for tag_data in tags_data:
      Tag.objects.create(tagging=tagging, **tag_data)

    for resource_data in resources_data:
      Resource.objects.create(tagging=tagging, **resource_data)

    for gameround_data in gamerounds_data:
      Gameround.objects.create(tagging=tagging, **gameround_data)

    for user_data in users_data:
      User.objects.create(tagging=tagging, **user_data)

    return tagging

  def to_representation(self, data):
    data = super().to_representation(data)
    return data

这是我要发送的 JSON 对象:

{
        "user": "creator",
        "gameround": 1,
        "resource": 602,
        "tag": "Redtagtestpost",
        "created": "2022-12-12T15:19:49.031000Z",
        "score": 0,
        "origin": ""
    }

但是,我在 Postman 中不断收到各种类型的“JSON 解析...”错误。

我经常遇到的一个错误是:

{"user":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]},"gameround":{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]},"resource":{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]},"tag":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}

我尝试对其他模型使用不同的字段,但似乎没有任何效果。

我的怀疑是我需要以某种方式访问​​请求中的数据并将其保存在正确的字段中,例如仅用户的用户名或指定它是我传递的 JSON 中的游戏回合的 ID,但我不知道如何做到这一点,也无法在网上找到有关此的任何信息。

如果我从序列化程序中删除以下内容:

tag = TagSerializer()
  resource = ResourceSerializer()
  gameround = GameroundSerializer()
  user = CustomUserSerializer(required=False)

我收到以下错误:

{"user":["Incorrect type. Expected pk value, received str."],"tag":["Incorrect type. Expected pk value, received str."]}

【问题讨论】:

  • 如果您的邮递员请求与您发布的相同,则您错过了creator周围的逗号:“user”:creator,
  • 谢谢,我现在修改了它,但我现在得到一个更长的错误。
  • payload 提供给TaggingSerializer 的数据不满足您定义的模型的要求,即在User.objects.create 中。尝试在TaggingSerializer 中添加一些简单的print() 语句并调试您的代码,错误很明显。
  • "这是我要发送的 JSON 对象:"...但是给定对象中的键与您尝试在代码中获取的键不匹配。例如,JSON 对象有"tag",但您的代码正在执行tags_data = validated_data.pop('tags')

标签: django django-rest-framework django-serializer


【解决方案1】:

将此添加到我的序列化程序解决了我的问题:

class TaggingSerializer(serializers.ModelSerializer):
  tag_id = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all(),
                                              required=False,
                                              source='tag',
                                              write_only=False)
  resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
                                                   required=True,
                                                   source='resource',
                                                   write_only=False)
  gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
                                                    required=False,
                                                    source='gameround',
                                                    write_only=False)
  user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
                                               required=False,
                                               source='user',
                                               write_only=False)
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2018-01-09
    相关资源
    最近更新 更多