Search code examples
pythondjangodjango-rest-framework

Django-Rest-FrameWork Post-Foreignkey


I am using DRF(Django-Rest-Framework) my Models.py

class Followers(models.Model):
    id = models.AutoField(primary_key=True)
    followers_no = models.IntegerField()

    
class Person(models.Model):
    followers = models.ForeignKey(Followers,null=True,blank=True,on_delete=models.CASCADE)
    name = models.CharField(max_length=120)
    age = models.IntegerField()
    
    def __str__(self) -> str:
        return self.name

my serializers.py

class Personserializer(ModelSerializer):
    followers = FollowerSerializer(read_only=True)
    class Meta:
        model = Person
        fields = "__all__"
    
    def validate(self,data):
        if data['age'] < 18:
            raise serializers.ValidationError('age should be more than 18')
        
        return data

i want to add data about Person With Followers Field for that i create views.py

def get(self, request):
        person_id = request.query_params.get('id')
        try:
            person = Person.objects.get(pk=person_id)
        except Exception as e:
            return Response({"status": False, "message": "Person not found"}, status=status.HTTP_404_NOT_FOUND)
        
        serializer = Personserializer(person)
        return Response({"status": True, "data": serializer.data}, status=status.HTTP_200_OK)
        
    def post(self, request):
        data = request.data
        serializer = Personserializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response({'status': True, "message": "Person created", "data": serializer.data}, status=status.HTTP_201_CREATED)
        return Response({"status": False, "message": "error", "error": serializer.error_messages}, status=status.HTTP_400_BAD_REQUEST)

if i try to post data using postman as below

{
        "followers": {
            "id": 1,
            "followers_no": 150
        },
        "name": "hello",
        "age": 19
}

it shows as null value of followers instead if i pass the data it should post

i Expect to store the data of followers field too


Solution

  • class FollowerSerializer(ModelSerializer):
        class Meta:
            model = Followers
            fields = '__all__'
    
    class Personserializer(ModelSerializer):
        followers = FollowerSerializer()
    
        class Meta:
            model = Person
            fields = "__all__"
        
        def validate(self,data):
           # remaining code here.....
        
        def create(self, validated_data):
        followers_data = validated_data.pop('followers', None)
        if followers_data:
            followers, created = Followers.objects.get_or_create(**followers_data)
            validated_data['followers'] = followers
        return Person.objects.create(**validated_data)
    

    Followers.objects.get_or_create(**followers_data) This line, If the Followers instance with id=1 and followers_no=150 does not exist, it will be created. If it does exist, it will be retrieved and associated.