Sia
Sia

Reputation: 159

How can i override create method in serializer with multiple nested fields in django?

I'm trying to create a writable nested serializer. I read django rest documents but in my case i have multiple nested fields and don't know how can solve that i get this error:

TypeError at /api/v1/libraries/ 'tel_number' is an invalid keyword argument for this function

models.py:

class RegisterRule(models.Model):
    picture        = models.BooleanField(default=False)
    passport       = models.BooleanField(default=False)
    education_rule = models.CharField(max_length=255)


class SpecificInformatin(models.Model):
    specific_name = models.CharField(max_length=255)
    description   = models.TextField(max_length=255)

    def __unicode__(self):
        return self.specific_name


class District(models.Model):

    district = models.CharField(max_length=2)

    def __unicode__(self):
        return self.district


class Address(models.Model):

    district      = models.ForeignKey(District, on_delete=models.CASCADE)
    square        = models.CharField(max_length=20)
    master_street = models.CharField(max_length=20)
    slave_street  = models.CharField(max_length=20)
    plaque        = models.CharField(max_length=3)

    def __unicode__(self):
        return self.slave_street


class Library(models.Model):

    name                      = models.CharField(max_length=30)
    address                   = models.OneToOneField(Address, on_delete=models.CASCADE, related_name='address')
    reading_room              = models.BooleanField(default=False)
    reading_room_start_time   = models.CharField(max_length=10, default='8:00')
    reading_room_end_time     = models.CharField(max_length=10, default='20:00')
    library_start_time        = models.CharField(max_length=10, default='8:00')
    library_end_time          = models.CharField(max_length=10, default='20:00')
    specific_information      = models.ManyToManyField(SpecificInformatin)
    register_rules            = models.ManyToManyField(RegisterRule)
    gender_days_in_week       = models.CharField(max_length=100, default='mens')
    manager_of_library        = models.CharField(max_length=50, default='shahrdari')
    tel_number                = models.CharField(max_length=11, null=True)
    email                     = models.EmailField(max_length=40, default="@.com")
    from_user                 = models.BooleanField(default=False)

    def __unicode__(self):
        return self.name

serializers.py:

class LibrarySerializer(serializers.ModelSerializer):

    address = AddressSerializer()
    specific_information = SpecificSerializer(many=True)
    register_rules = RegisterRulesSerialzers(many=True)

    class Meta:
        model = Library
        fields = ('id', 'name', 'address', 'reading_room', 'reading_room_start_time'
                  , 'reading_room_end_time', 'library_start_time', 'library_end_time'
                  , 'specific_information', 'register_rules', 'gender_days_in_week'
                  , 'manager_of_library', 'tel_number', 'email', 'from_user')

    def create(self, validated_data):
        address_data = validated_data.pop('address')
        address = Address.objects.create(**validated_data)

        register_rules_data = validated_data.pop('register_rules')
        register_rules = RegisterRule.objects.create(**validated_data)

        specific_information_data = validated_data.pop('specific_information')
        specific_information = SpecificInformatin.objects.create(**validated_data)

        library = Library.objects.create(**validated_data)

        library.address(address=address, **address_data)

        for data in register_rules_data:
            library.register_rules.add(register_rules=register_rules, **data)
        for data in specific_information_data:
            library.specific_information.add(specific_information=specific_information, **data)

        return library

Upvotes: 4

Views: 7288

Answers (1)

SHIVAM JINDAL
SHIVAM JINDAL

Reputation: 2974

You are doing some mistake. when you pop some data from dict it return value of particular data.

create(self, validated_data):
        address_data = validated_data.pop('address')
        address = Address.objects.create(**address_data)

        register_rules_data = validated_data.pop('register_rules')

        specific_information_data = validated_data.pop('specific_information')

        library = Library.objects.create(address=address, **validated_data)

        for data in register_rules_data:
            register_rules = RegisterRule.objects.create(**data)
            library.register_rules.add(register_rules)
        for data in specific_information_data:
             specific_information = SpecificInformatin.objects.create(**data)
             library.specific_information.add(specific_information)

        return library

I think this code will work for you.

Upvotes: 4

Related Questions