Hisham
Hisham

Reputation: 253

how to set foreignkey value in child serializer in django rest framework when the parent record exists

I have two models first as parent model "Country", that filled before the second one as child model "City". as the following

class Country(models.Model):
    name = models.CharField(max_length=35)
    icon = models.ImageField()

    def __str__(self):
        return self.name


class City(models.Model):
    name = models.CharField(max_length=35)
    country = models.ForeignKey(to=Country, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

My serializers.py for my need as following :

class CountrySerializer(ModelSerializer):
    class Meta:

        model = Country
        fields = '__all__'

class CitySerializer(ModelSerializer):
    country = serializers.PrimaryKeyRelatedField(queryset=Country.objects.all())

    class Meta:

        model = City
        fields = ('name', 'country')

view.py

class CountryAPIView(ListAPIView):
    queryset = Country.objects.all()
    serializer_class = CountrySerializer
    permission_classes = [AllowAny, AllowAnonymous]


class CityAPIView(ListAPIView):
    queryset = City.objects.all()
    serializer_class = CitySerializer
    permission_classes = [AllowAny, AllowAnonymous]

    def post(self, request):

        serializer = CitySerializer(data=request.data)
        if serializer.is_valid(raise_exception=ValueError):
            serializer.create(validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.error_messages,
                        status=status.HTTP_400_BAD_REQUEST)

now when i run get api it run and gives me a result fine . But when im trying to create a new city and set "country":"id" in json i got this error

Cannot assign "2": "City.country" must be a "Country" instance.

So if i was not clear ,, what i need is exactly set foreign key to city when i create city ,, not create city and country,,

please any one had a solution help, because i tried many ways and read the django rest framework docs about this point but i didn't got it.

Upvotes: 4

Views: 1707

Answers (2)

JPG
JPG

Reputation: 88539

First of all, the raise_exception should be a boolean value (either True or False)

You could avoid this error by using inheriting the view class from ListCreateAPIView


from rest_framework.generics import ListCreateAPIView

class CityAPIView(ListCreateAPIView): queryset = City.objects.all() serializer_class = CitySerializer permission_classes = [AllowAny, AllowAnonymous]

You don't want to use the post() method if you're using ListCreateAPIView, because DRF will take care of that part well.

Suggestion
Since you're dealing with CRUD functionalities of the model, you can use the DRF's ModelViewset class

Upvotes: 1

Ehsan Nouri
Ehsan Nouri

Reputation: 2040

you are not using the validated data to create a new city, just change this line:

        serializer.create(validated_data=request.data)

to this:

        serializer.save()

when you perform serializer.save(), the serializer will use its validated data.

also, DRF has a generic view(ListCreateAPIView) that covers your use-case.

Upvotes: 1

Related Questions