[Fixed]-Django Rest Framework create user and user profile

27👍

Indeed, Django Rest Framework can’t handle this job with nested relationships then you have to implement these methods yourself. I will give you some example of what your code should look like.

Your view :

class UserList(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticatedOrWriteOnly,)
    serializer_class = UserSerializer

    def post(self, request, format=None):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Now, the save method of your serializer will call a create method when you want to create an object and update method when you want to update an object. So let’s implement the create method of your UserSerializer which will create the profile and the user. Here is a simple example of what your UserSerializer should look like :

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(required=True)
    class Meta:
        model = User
        fields = ('url', 'email', 'profile', 'created',)

    def create(self, validated_data):

        # create user 
        user = User.objects.create(
            url = validated_data['url'],
            email = validated_data['email'],
            # etc ...
        )

        profile_data = validated_data.pop('profile')
        # create profile
        profile = Profile.objects.create(
            user = user
            first_name = profile_data['first_name'],
            last_name = profile_data['last_name'],
            # etc...
        )

        return user

As I said, this is an example, you have to complete it to do what you want to do but now, you know how to do it 🙂 To define the behavior during an update, implement an update method.

3👍

This might be late but why not bypass drf entirely and relegate profile creation trigger to models using signals like so:

models.py

class User(AbstractBaseUser):
      pass
class UserProfile(models.Model):
      user =  models.OneToOneField(User, on_delete=models.CASCADE, related_name='customer_profile')
      country = models.CharField(blank=True, max_length=250)

signals.py

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(
            user = instance
        )

this basically triggers a corresponding profile row creation once a user has been created via any means; admin, drf etc.

then you can use serializers to update the data.
hope this helps anyone else stumbling here

Leave a comment