0
votes

I have to save objects of two different models and using nested serializers. I am using following django rest docs:- https://www.django-rest-framework.org/api-guide/relations/#Writable%20nested%20serializers

I have followed many solutions on stackoverflow however I am unable to figure the following error:-

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

I checked my serializers by printing request.data and they are working fine. However, serializer.is_valid(raise_exception=True) raises the above error.

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)

Following code I am using on frontend side( 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
please add error response in questionanjaneyulubatta505
Can you clarify the error you've got? Just 400 isn't enough to understand the cause.JPG
I am getting Bad Request: /api/register "POST /api/register HTTP/1.1" 400 50 as the only error response.Vineet
share how are you sending request to the API endpoint ?anjaneyulubatta505
@AnjaneyuluBatta added nowVineet

1 Answers

0
votes

There is no property attribute in your InterestedUser model, but a property_set instead and that is because you used a ForeignKey, thus InterestedUser <-> Property is a 1:N relationship.

What can you do?

  • Add related_name=properties to your owner field at Property
  • At your UserSerializer, property = ReportAPISerializer(source='properties', many=True)

There are other issues related to how you designed these objects, I would suggest a few things for you to keep in mind:

  • If multiple users can be interested in multiuple properties, go for a ManyToMany
  • Avoid using property as the serializer field name, property is a reserved python word.