-1

Why am I getting the Integrity Error despite the fact that I'm checking that the username is unique here: (I also tried try/expect IntegretyError instead of e.count())

# -*- coding: utf-8 -*-

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


from slugify import slugify



class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
    username = models.CharField(max_length=30, blank=True, unique=True) #should be true on signup
    name = models.CharField(max_length=30, blank=True)
    bio = models.TextField(max_length=500, blank=True)
    location = models.CharField(max_length=30, blank=True)
    email = models.EmailField()  #should be true on signup
    avatar_url = models.URLField(default="https://image.flaticon.com/icons/png/512/64/64572.png")


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


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

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.profile.save(commit=False)




    from allauth.account.signals import user_logged_in, password_set, user_signed_up
    from django.db.models.signals import post_save
    from django.dispatch import receiver, Signal


    @receiver(user_logged_in)
    def populate_profile(sociallogin, user, **kwargs):

        # picture_url = ""
        if sociallogin.account.provider == 'github':

            user_data = user.socialaccount_set.filter(provider='github')[0].extra_data
            print(user_data)
            username = user_data['login']
            avatar_url = user_data['avatar_url']
            email = user_data['email']
            name = user_data['name']
            bio =  user_data['bio']
            location = user_data['location']


        if sociallogin.account.provider == 'twitter':
            user_data = user.socialaccount_set.filter(provider='twitter')[0].extra_data
            print(user_data)
            username = user_data['screen_name']
            avatar_url = user_data['profile_image_url'].replace("_normal", "")
            email = user_data['email']
            name = user_data['name']
            bio =  user_data['description']
            location = user_data['location']

        e = Profile.objects.filter(username=username)

        if e.count() > 0:
            user.profile.username = slugify(name)
        else:
            user.profile.username = username
        #except IntegrityError:

        user.profile.avatar_url = avatar_url
        user.profile.email = email
        user.profile.name = name
        user.profile.bio = bio
        user.profile.location = location
        user.profile.save()
4m1nh4j1
  • 4,289
  • 16
  • 62
  • 104

1 Answers1

0

Well, probably this line of code is the issue:

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

Because, every-time user is saved, this signal will be triggered, hence will try to create a profile. Instead, use the commented out code section:

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

Then only if the a user is created, then a profile will be created.

Also I am not sure if the following code will work. Because model's save() method does not have any keyword argument named commit. So it might throw error. To be honest, you don't need that signal, so you can remove that as well.

ruddra
  • 50,746
  • 7
  • 78
  • 101