【问题标题】:Unable to save objects using nested serializer in django rest framework无法在 django rest 框架中使用嵌套序列化程序保存对象
【发布时间】:2019-10-27 20:12:29
【问题描述】:

我必须保存两个不同模型的对象并使用嵌套的序列化程序。我正在使用以下 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) 会引发上述错误。

序列化器.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
                              });
  },

【问题讨论】:

  • 请添加有问题的错误响应
  • 你能澄清你遇到的错误吗?仅 400 条不足以了解原因。
  • 我收到 Bad Request: /api/register "POST /api/register HTTP/1.1" 400 50 作为唯一的错误响应。
  • 分享你如何向 API 端点发送请求?
  • @AnjaneyuluBatta 现已添加

标签: django django-rest-framework


【解决方案1】:

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

你能做什么?

  • related_name=properties 添加到您的owner 字段Property
  • 在您的UserSerializerproperty = ReportAPISerializer(source='properties', many=True)

还有其他与您如何设计这些对象有关的问题,我建议您牢记以下几点:

  • 如果多个用户可能对多个属性感兴趣,请联系ManyToMany
  • 避免使用property 作为序列化器字段名称,property 是 Python 的保留字。

【讨论】:

    猜你喜欢
    • 2019-12-23
    • 2021-06-23
    • 1970-01-01
    • 2016-05-14
    • 2020-07-07
    • 2013-05-05
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多