BigJim
BigJim

Reputation: 23

Cannot create Django user due to UserProfile creation throwing IntegrityError

Django is giving me an integrity error when creating users. From my models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)

    age = models.DateField()
    city = models.CharField(max_length=30)
    state = models.CharField(max_length=20)
    country = models.CharField(max_length=30)
    primary_language = models.CharField(max_length=30)
    secondary_language = models.CharField(max_length=30, blank=True, null=True)
    tertiary_language = models.CharField(max_length=30, blank=True, null=True)

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

post_save.connect(create_user_profile, sender=User)

The above code is directly from the Django site. On to the views.py, where I create the user:

def create_user_and_profile(request):
    form = RegistrationForm(request.POST)
    if form.is_valid():
        # User is saved to DB here
        user = User.objects.create_user( 
            username = form.cleaned_data['username'],
            password = form.cleaned_data['password1'],
            email = form.cleaned_data['email']
        )
        user.first_name = form.cleaned_data['first_name']
        user.last_name = form.cleaned_data['last_name']
        user.save()
        # TODO remaining user creation code goes here
        profile = user.get_profile()

        profile.age = form.cleaned_data['age'],
        profile.city = form.cleaned_data['city'],
        profile.state = form.cleaned_data['state'],
        profile.country = form.cleaned_data['country'],
        profile.primary_language = form.cleaned_data['primary_language'],
        profile.secondary_language = form.cleaned_data['secondary_language'],
        profile.tertiary_language = form.cleaned_data['tertiary_language']
        profile.save()
        return user
    else:
        variables = RequestContext(request, {'form': form})
        return render_to_response('registration/register.html', variables)

Django will create the user object (as a result of User.objects.create_user) and then blow up. I even tried this in the shell after importing my model file - still blows up. Here is the error that is being thrown:

IntegrityError at /my_url/

myApp_userprofile.age may not be NULL

What I THINK is occurring is that when Django saves the user object, due to the callback it created the UserProfile obj as well. Since it has no data to create the UserProfile with, it throws the integrity error due to attempting to create a database record with NULL as inputs.

Disclosure: I am using sqlite3 and have deleted and added tables multiple times as I have refined my schema. However, as best I can tell, the DB is correct - I walked through each of the tables by hand.

I cannot find a single example of this occurring anywhere else. Why would Django give me the option to create a UserProfile that violates DB constraints with it's very creation? I have been pulling my hair out over this for the last two days and would greatly appreciate any insight. THANKS!

EDIT: Just dropped the DB in order to start from scratch. syncdb throws the SAME ERROR upon creation of my superuser account. What the hell is going on?

Upvotes: 0

Views: 1274

Answers (3)

BigJim
BigJim

Reputation: 23

Answered my own question. When a User is created & saved, the UserProfile is created/saved as well - this we know. What I did not know is that Dates, Booleans and integers cannot be null as stated here. So, the solution is to change this line of the UserProfile class:

age = models.DateField()

to

age = models.DateField(null=True)

This allows the UserProfile to be saved to the DB without being populated, and for me to retrieve it with get_profile() and populate it later.

Upvotes: 1

machaku
machaku

Reputation: 1196

I think you have to add AUTH_PROFILE_MODULE to you settings.py so as to automatically create a user profile after a new user is saved. Did you check this documentation?

Upvotes: 0

szaman
szaman

Reputation: 6756

Did you check if age is not empty? Why not to create user via userprofile? What i mean is:

profile.first_name = 'abc'
profile.last_name = 'abc'
profile.age = Date(2000, 1, 1)
profile.save()

Upvotes: 0

Related Questions