Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_profile.user_id

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading