【问题标题】:Django-Rest-Framework - How to Deserialize Custom Nested FieldDjango-Rest-Framework - 如何反序列化自定义嵌套字段
【发布时间】:2017-06-07 03:11:42
【问题描述】:

我有一个名为“邀请”的模型,它搜索现有用户并在他们不存在时创建一个:

from django.contrib.gis.db import models
from users.models import CustomUser

class Hangout(models.Model):
  name = models.CharField(max_length=255)

class InviteManager(models.Manager):
  def create_invite(self, hangout, phone):
    (user, did_create) = CustomUser.objects.get_or_create(phone=phone)
    invite = self.create(status=status, hangout=hangout, arrival_time=arrival_time, user=user)
    return invite

class Invite(models.Model):
  hangout = models.ForeignKey(Hangout, on_delete=models.CASCADE, related_name='invites')
  user = models.ForeignKey(CustomUser)

  objects = InviteManager()

我在反序列化它时遇到了很多麻烦。我想通过这个帖子请求创建一个包含嵌套邀请的环聊:

{ 'name': 'Bobs House',
  'invites': [
             { 'phone': '5127914819', 'name': 'Bob1' },
             { 'phone': '0000000000', 'name': 'Bob2' },
             { 'phone': '0000000001', 'name': 'Bob3' },
             { 'phone': '0000000002', 'name': 'Bob3' },
             { 'phone': '0000000003', 'name': 'Bob4' }
             ]
}

我希望 Invite 序列化程序检查电话是否存在并且长度为 10 位。我在设置一系列序列化程序以工作时遇到了很多麻烦。我尝试了herehere 解决方案的组合,但是模型上根本没有的嵌套反序列化器和自定义创建字段的组合让我发疯。任何帮助深表感谢!谢谢

【问题讨论】:

    标签: python django serialization django-rest-framework deserialization


    【解决方案1】:

    我最终使用了与模型上的字段不同的序列化程序。这是工作代码,以防它对某人有所帮助:

    from rest_framework import serializers
    from . import models
    from users.models import CustomUser
    
    class InviteSerializer(serializers.ModelSerializer):
      phone = serializers.CharField()
      name = serializers.CharField(required=False)
    
      class Meta:
        extra_kwargs = { 'name': { 'read_only': True },
                         'phone': { 'read_only': True }}
    
        fields = (
          'phone',
          'name',
          )
        model = models.Invite
    
      def validate(self, data):
        return data
    
      def create(self, validated_data):
        phone = validated_data.pop('phone')
        name = validated_data.pop('name', None)
        (user, did_create) = CustomUser.objects.get_or_create(phone=phone)
        if (user.display_name is None) and (name is not None):
          user.display_name = name
        user.save()
        instance = self.Meta.model.objects.create(user=user, hangout=validated_data['hangout'])
        instance.save()
    
    class HangoutSerializer(serializers.ModelSerializer):
      name = serializers.CharField(required=True)
      invites = InviteSerializer(many=True)
    
      class Meta: 
        extra_kwargs = { 'phones': {'write_only': True, 'required': True } }
    
        fields = (
          'invites',
          'name',
          )
    
        model = models.Hangout
    
      def create(self, validated_data):
        invites_data = validated_data.pop('invites')
        instance = self.Meta.model(**validated_data)
        instance.save()
    
        serializer = InviteSerializer(data=invites_data, many=True)
        if serializer.is_valid(raise_exception=True):
          invites = serializer.save(hangout=instance)
          return instance
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      相关资源
      最近更新 更多