Lin
Lin

Reputation: 93

How to update (put/post request) related fields with Django rest api?

I'm new to Django. Within the Django rest framework, I'm struggling with the put & post request on a table that's linked to other table(s).

The main table I want to update via API is person, that's basically where contact details are kept. It joins to 2 other tables, email, phone, where each of them only contains 1 piece of information (as their name stated). What I'm trying to achieve is that when I submit a put/post request to person's api, it also updates email, phone without needing to update each of them respectively.

Below are some code:

Models:

class Person(models.Model):
    id = models.AutoField(primary_key=True)
    last_name = models.CharField(max_length=50)
    first_name = models.CharField(max_length=50)
    email = models.ManyToManyField('Email')
    phone = models.ManyToManyField('Phone')

    class Meta:
        ordering = ['last_name', 'first_name']

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

class Phone(models.Model):
    phone = models.CharField(max_length=50, blank=True, null=True)
    def __str__(self):
        return f'{self.phone}'

class Email(models.Model):
    email = models.CharField(max_length=50, blank=True, null=True)
    def __str__(self):
        return f'{self.email}'

Serializers:

class PersonSerializer(serializers.ModelSerializer):
    email = serializers.StringRelatedField(many=True)
    phone = serializers.StringRelatedField(many=True)

    class Meta:
        model = Person
        fields = ('id', 'last_name', 'first_name', 'email', 'phone')

class PhoneSerializer(serializers.ModelSerializer):
    class Meta:
        model = Phone
        fields = ('id', 'phone')

class EmailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Email
        fields = ('id', 'email')

Views:

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

class PhoneViewSet(RetrieveAPIView):
    queryset = Phone.objects.all()
    serializer_class = PhoneSerializer

class EmailViewSet(RetrieveAPIView):
    queryset = Email.objects.all()
    serializer_class = EmailSerializer

In the person API detailed view, under put request, email and phone fields are currently grayed out and says "No items to select", I'm hoping to be able to enter values in there, and can successfully submit the put/post request via the front end (React) of my app.

enter image description here

I've been stucking here for weeks, any help would be appreciated!

Thanks

Upvotes: 1

Views: 1483

Answers (1)

Lin
Lin

Reputation: 93

I might be able to answer my own question now, also in case someone else is having the same issue. This is how I resolved it.

As @JPG mentioned, you can also override the update and/or create method to define how to handle related fields explicitly, but there is a way easier approach.

from drf_writable_nested import WritableNestedModelSerializer

class PersonSerializer(WritableNestedModelSerializer):
    last_name = serializers.CharField(required=True, max_length=100)
    first_name = serializers.CharField(required=True, max_length=100)
    address = AddressSerializer(many=True)
    email = EmailSerializer(many=True)
    phone = PhoneSerializer(many=True)


    class Meta:
        model = Person
        fields = ('id', 'last_name', 'first_name', 'address', 'email', 'phone', 'group')

Upvotes: 1

Related Questions