Search code examples
djangodjango-modelsdjango-users

How to correctly create the "User extra info" object. / IntegrityError "Column *something* cannot be null"


In order to add informations to my auth.User model I followed this piece of doc. I would like to link a User to a Society (assuming a user is a client for example) and to a job in this society. So here's my code:

societies/models.py:

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


class UserProfile(models.Model):
    """
    Stores the user informations except
    login basic informations.
    """
    user = models.OneToOneField(User)
    firstname = models.CharField(max_length=128)
    lastname = models.CharField(max_length=128)
    society = models.ForeignKey('Society')
    job = models.ForeignKey('UserJob')


class Society(models.Model):
    """
    Stores the informations about the societies.
    """
    name = models.CharField(max_length=128)


class UserJob(models.Model):
    """
    Stores the user job category in the society.
    """
    name = models.CharField(max_length=64)


def create_user_profile(sender, instance, created, **kwargs):
    """
    Uses the post_save signal to link the User saving to
    the UserProfile saving.
    """
    if created:
        UserProfile.objects.create(user=instance)


#the instruction needed to use the post_save signal
post_save.connect(create_user_profile, sender=User)

societies/admin.py:

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from societies.models import UserProfile, Society, UserJob


class UserProfileInline(admin.StackedInline):
    """
    Defines an inline admin descriptor for UserProfile model
    which acts a bit like a singleton
    """
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'profile'


class UserAdmin(UserAdmin):
    """
    Defines a new User admin.
    """
    inlines = (UserProfileInline, )

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

admin.site.register(Society)
admin.site.register(UserJob)

I added the UserProfileInline in order to have the fields on my admin-site User form. I added this line to my settings.py:

AUTH_PROFILE_MODULE = 'societies.UserProfile'

The problem is then that when I try to create a User through my User form on the admin-site, including filling the UserProfile-specific fields, I get this:

IntegrityError at /admin/auth/user/add/

(1048, "Column 'society_id' cannot be null")

Because I've specified a society on the form I'm asking my self if the problem is not coming from the signal handling with my create_user_profile function. Considering the doc I mentionned earlier, there is nothing more to do. However, don't I have to precise how to fill the UserProfile fields firstname, lastname, society and job through the UserProfile.create(...) call ? (in addition to the "user=instance" parameter). In this case, I don't know how to get the right elements to fill the parameters. In the doc nothing is done concerning the "accepted_eula" and "favorite_animal" so I'm certainly wrong... isn't it ?

Thank you so much for any response. I apologize for my language.


Solution

  • I found my mistake, I had to add a default value to the Society and UserJob foreignkey fields in the UserProfile model. Another solution would be to specify they can be null.

    Sorry for this lack of attention.