I’m having issues with registering a user in my project. I have a custom serializer that inherits from the RegisterView of dj_rest_auth. My code is:
views.py
class ProfileDetail(APIView):
def get_object(self, pk):
try:
return Profile.objects.get(pk=pk)
except Profile.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
profile = self.get_object(pk)
serializer = ProfileSerializer(profile)
return Response(serializer.data)
class CustomRegisterView(RegisterView):
serializer_class = CustomRegisterSerializer
serializer.py
class CustomRegisterSerializer(RegisterSerializer):
user_type = serializers.ChoiceField(choices=[('seeker', 'Seeker'), ('recruiter', 'Recruiter')])
class Meta:
model = User
fields = "__all__"
def get_cleaned_data(self):
data = super().get_cleaned_data()
data['user_type'] = self.validated_data.get('user_type', '')
return data
def save(self, request):
user = super().save(request)
user_type = self.validated_data.get('user_type')
Profile.objects.create(user=user, user_type=user_type)
return user
models.py
class Profile(models.Model):
class Type(models.TextChoices):
seeker = "Seeker"
recruiter = "Recruiter"
base_type = Type.seeker
user = models.OneToOneField(User, on_delete=models.CASCADE)
user_type = models.CharField(choices=Type.choices, default=base_type, max_length=20)
signals.py
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance, user_type='')
post_save.connect(create_user_profile, sender=User)
I expect the code to return a 200 after I perform a POST request.
>Solution :
You likely defined a signal to create a Profile, so when the User object is saved, it already creates a Profile, so creating a second one for the same user is no longer possible. This is one of many reasons not to work with signals.
It thus might be better to just omit the signal, and create the Profile where it should be created: in the corresponding view(s) and ModelAdmin. If removing the signal is really not possible, you can work with an .update_or_create call instead:
class CustomRegisterSerializer(RegisterSerializer):
user_type = serializers.ChoiceField(
choices=[('seeker', 'Seeker'), ('recruiter', 'Recruiter')]
)
class Meta:
model = User
fields = "__all__"
def get_cleaned_data(self):
data = super().get_cleaned_data()
data['user_type'] = self.validated_data.get('user_type', '')
return data
def save(self, request):
user = super().save(request)
defaults = {'user_type': self.validated_data.get('user_type')}
Profile.objects.update_or_create(
user=user, defaults=defaults, create_defaults=defaults
)
return user