无法在Django Rest框架中使用嵌套序列化器保存对象

时间:2019-06-13 09:03:46

标签: django django-rest-framework

我必须保存两个不同模型的对象并使用嵌套的序列化器。我正在使用以下django rest文档:- https://www.django-rest-framework.org/api-guide/relations/#Writable%20nested%20serializers

我在stackoverflow上遵循了许多解决方案,但是我无法确定以下错误:-

Bad Request: /api/register
"POST /api/register HTTP/1.1" 400 50

我通过打印request.data检查了序列化程序,它们工作正常。但是,serializer.is_valid(raise_exception=True)会引发上述错误。

serializers.py

# Serializer for report

class ReportAPISerializer(serializers.ModelSerializer):
    latitude = serializers.FloatField()
    longitude = serializers.FloatField()

    class Meta:
        model = Property
        fields = ('longitude', 'latitude', 'consumer_type', 'area', 'avg_monthly_bill',)


# Serializer to get user details

class UserSerializer(serializers.ModelSerializer):
    property = ReportAPISerializer()

    class Meta:
        model = InterestedUser
        fields = ('full_name', 'phone_no', 'email', 'property')

    def create(self, validated_data):
        property_data = validated_data.pop('property')
        user = InterestedUser.objects.create(**validated_data)
        Property.objects.create(
            owner=user,
            location=Point(property_data['latitude'], property_data['longitude']),
            area=property_data['area'],
            consumer_type=property_data['consumer_type'],
            avg_monthly_bill=property_data['avg_monthly_bill']
        )
        return user

views.py

class RegisterAPIVIew(CreateAPIView):
    serializer_class = UserSerializer

models.py

class InterestedUser(AbstractBaseUser, PermissionsMixin):
    user_id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True)

    date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    full_name = models.CharField(max_length=50, default="")
    email = models.EmailField(blank=False, unique=True)
    phone_no = models.CharField(max_length=10, default="")
    active = models.BooleanField(default=False)
    staff = models.BooleanField(default=False)
    admin = models.BooleanField(default=False)
    password = models.CharField(default="", max_length=128)
    is_superuser = None

    objects = InterestedUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    class Meta:
        verbose_name = 'user'
        verbose_name_plural = 'users'

    def __str__(self):
        return "%s -- %s" % (self.full_name, self.email)

    def get_full_name(self):
        if self.full_name:
            return self.full_name

        return self.email

    def get_short_name(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_admin(self):
        return self.admin

    @property
    def is_active(self):
        return self.active



class Property(models.Model):
    property_id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    avg_monthly_bill = models.FloatField(default=0.0)
    consumer_type = models.CharField(max_length=15, null=True)
    location = models.PointField(null=True, blank=True)
    area = models.FloatField(null=True)

以下我在前端使用的代码(usign Vue):-

createAccount(fullName, email, phoneNo, latitude, longitude, area, consummerType, avgMonthlyBill){
    console.log(fullName + " ", email + " " + phoneNo + latitude + " " + longitude + " " + area + " " + consummerType + " " + avgMonthlyBill)
    let property = {
      'latitude':latitude,
      'longitude':longitude,
      'area':area,
      'consumer_type':consummerType,
      'avg_monthly_bill':avgMonthlyBill
    }
    return session.post('register', {
                                'full_name':fullName, 
                                'email':email, 
                                'phone_no':phoneNo, 
                                'property':property
                              });
  },

1 个答案:

答案 0 :(得分:0)

property模型中没有InterestedUser属性,而是property_set,这是因为您使用了ForeignKey,因此InterestedUser <-> Property是1:N关系。

你能做什么?

  • related_name=properties的{​​{1}}字段中添加owner
  • 在您的PropertyUserSerializer

还有其他与如何设计这些对象有关的问题,我建议您记住一些事项:

  • 如果多个用户可能对多属性感兴趣,请选择property = ReportAPISerializer(source='properties', many=True)
  • 避免使用ManyToMany作为序列化器字段名称,property是保留的python单词。