0

I have a create_or_update_user_profile methods to the User model, whenever a save event occurs, but I added a new method set_initial_user_names to save a url, then now it shows me an error IntegrityError at /accounts/social/signup/ UNIQUE constraint failed: auth_profile.user_id

class UserProfile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=170, blank=True)
    avatar_url = models.CharField(max_length=256, blank=True)
    facebook_url = models.CharField(max_length=40, blank=True)
    twitter_url = models.CharField(max_length=40, blank=True)
    instagram_url = models.CharField(max_length=40, blank=True)
    web_url = models.CharField(max_length=40, blank=True)

    class Meta():
        db_table = 'auth_profile'

    def __str__(self):
        return self.user.username


@receiver(user_signed_up)
def set_initial_user_names(request, user, sociallogin=None, **kwargs):

    preferred_avatar_size_pixels = 256

    picture_url = "http://www.gravatar.com/avatar/{0}?s={1}".format(
        hashlib.md5(user.email.encode('UTF-8')).hexdigest(),
        preferred_avatar_size_pixels
    )

    if sociallogin:
        if sociallogin.account.provider == 'twitter':
            name = sociallogin.account.extra_data['name']
            user.first_name = name.split()[0]
            user.last_name = name.split()[1]

        if sociallogin.account.provider == 'facebook':
            user.first_name = sociallogin.account.extra_data['first_name']
            user.last_name = sociallogin.account.extra_data['last_name']

            picture_url = "http://graph.facebook.com/{0}/picture?width={1}&height={1}".format(
                sociallogin.account.uid, preferred_avatar_size_pixels)

        if sociallogin.account.provider == 'google':
            user.first_name = sociallogin.account.extra_data['given_name']
            user.last_name = sociallogin.account.extra_data['family_name']
            picture_url = sociallogin.account.extra_data['picture']


    profile = UserProfile(user=user, avatar_url=picture_url)
    profile.save()


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

IntegrityError at /accounts/social/signup/ UNIQUE constraint failed: auth_profile.user_id

David Buck
  • 3,752
  • 35
  • 31
  • 35
Kedinn Turpo
  • 95
  • 1
  • 1
  • 5

1 Answers1

1

You are trying to create user twice for the same user.

First one is created in create_or_update_user_profile handler right after user instance creation. Second is here:

@receiver(user_signed_up)
def set_initial_user_names(request, user, sociallogin=None, **kwargs):
    ...

    profile = UserProfile(user=user, avatar_url=picture_url)  
    profile.save()  # <--- HERE

receiver(user_signed_up) is triggered after user object is already created, so user profile already was create by create_or_update_user_profile.

So to fix the problem you should use existing user profile, not create a new one:

@receiver(user_signed_up)
def set_initial_user_names(request, user, sociallogin=None, **kwargs):
    ...

    user.userprofile.avatar_url = picture_url 
    user.userprofile.save()
zymud
  • 2,221
  • 16
  • 24