0

I am new to DRF I am saving a user details and his pets details .

Here is the model

class Users(models.Model):
    id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=255, blank=True)
    last_name = models.CharField(max_length=255, blank=True)
    job = models.CharField(max_length=255, blank=True)
    age = models.CharField(max_length=255, blank=True)

class PetDetails(models.Model):
    user = models.ForeignKey(
        Users, on_delete=models.CASCADE, blank=True, null=True)
    pet_name = models.CharField(max_length=255, blank=True)
    pet_color = models.CharField(max_length=255, blank=True)
    pet_category = models.CharField(max_length=255, blank=True)

In this I need to save both user and his pets in a single Post request.

So I created a serializer like this

class UserCreateSerializer(ModelSerializer):

    pet = PetDetailCreateSerializer(many=True)

    class Meta:
        model = Users
        fields = ['first_name','last_name','job','age', 'pet']

    def create(self, validated_data):
        pets_data = validated_data.pop('pet')
        user_obj = Users.objects.create(**validated_data)
        for pet in pets_data:
            PetDetails.objects.create(user=user_obj, **pet)
        return user_obj

The issue I am facing is if a single person can have multiple pets.

For Example John is a user and he having two Pets.

So in this cases two users object will creating .How to resolve this

OR is there any other methods for handling this

My views is

class UserCreateView (CreateAPIView):
    serializer_class = UserCreateSerializer
Anoop
  • 505
  • 8
  • 23

1 Answers1

2

One way is to check if user already exists by using get_or_create:

user_obj = Users.objects.get_or_create(**audit_data)

But better way, I think, is to create user with multiple pets instead:

class UserCreateSerializer(ModelSerializer):

    petdetails_set = PetDetailCreateSerializer(many=True)

    class Meta:
        model = Users
        fields = ['first_name','last_name','job','age', 'petdetails_set']

    def create(self, validated_data):
        pets_data = validated_data.pop('pet')
        user_obj = User.objects.create(**validated_data)
        for pet in pets_data:
            PetDetails.objects.create(user=user_obj, **pet)
        return user_obj

Also, I advice to use separate endpoints/serializers for user creation.

Anoop
  • 505
  • 8
  • 23
Charnel
  • 4,222
  • 2
  • 16
  • 28
  • Thanks I will try this Just having one doubt in this case also I need to pass the data as a row data in postman , right ? – Anoop Apr 03 '20 at 06:54
  • @David yes, you need to pass data as array in Postman. [This](https://stackoverflow.com/a/23735006/4996863) post might help. – Charnel Apr 03 '20 at 07:06
  • i am getting an error like this "detail": "JSON parse error - Expecting ',' delimiter: line 22 column 25 (char 527)" – Anoop Apr 03 '20 at 07:34
  • I fix that issue, but I get another issue regarding this Got AttributeError when attempting to get a value for field `pet` on serializer `UserCreateSerializer`. The serializer field might be named incorrectly and not match any attribute or key on the `Users` instance. Original exception text was: 'Users' object has no attribute 'pet'. – Anoop Apr 03 '20 at 08:36
  • Are you sure the code is exactly the same I showed and used properly? [Here](https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers) you can find the example in docs. – Charnel Apr 03 '20 at 09:26
  • Yeah.... If I remove that pet in fields.... It showing The field 'pet' was declared on serializer UserCreateSerializer, but has not been included in the 'fields' option. If I add that to pet to fields it showing " Got AttributeError when attempting to get a value for field pet on serializer UserCreateSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Users instance. Original exception text was: 'Users' object has no attribute 'pet'. – Anoop Apr 03 '20 at 09:49
  • class UserCreateView (CreateAPIView): serializer_class = UserCreateSerializer – Anoop Apr 03 '20 at 10:17
  • Sorry, I just realized that this is reverse lookup on FK and it should be defined as _set (in case you didn't specified `related_name` attribute on FK field). I updated answer - please check. – Charnel Apr 03 '20 at 10:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210918/discussion-between-david-and-charnel). – Anoop Apr 04 '20 at 07:21