[Django]-Django create userprofile if does not exist

22đź‘Ť

âś…

Usually user profile objects are created right after the user instance is created. This is easily accomplished using signals.

The problem I have is that I use a single sign-in login so if someone logs in on another system and then goes to my site they are logged in but don’t get a user profile created (I create a user profile when they log in).

Apparently using signals at user creation time won’t work for you. One way to accomplish what you are trying to do would be to replace calls to request.user.get_profile() with a custom function. Say get_or_create_user_profile(request). This function can try to retrieve an user’s profile and then create one on the fly if one doesn’t exist.

For e.g.:

def get_or_create_user_profile(request):
    profile = None
    user = request.user
    try:
        profile = user.get_profile()
    except UserProfile.DoesNotExist:
        profile = UserProfile.objects.create(user, ...)
    return profile

3đź‘Ť

I found this solution I like to use at this site: http://www.turnkeylinux.org/blog/django-profile

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

Using a property like this seems cleaner than defining a new method, but I agree it’d be a pain to go through your code base and change user.get_profile() references to user.profile ones.

Then again, isn’t that what your global file search and replace function is for?

👤bskinnersf

2đź‘Ť

Building on bskinner’s answer and in response to sqwerty’s comment, you might use this:

def get_or_create_profile(user):
    """
    Return the UserProfile for the given user, creating one if it does not exist.

    This will also set user.profile to cache the result.
    """
    user.profile, c = UserProfile.objects.get_or_create(user=user)
    return user.profile

User.profile = property(get_or_create_profile)

So this will create a profile if needed, and User.profile.field = "deep" then User.profile.save() works.

👤user256434

2đź‘Ť

Revised as below. Otherwise, “AttributeError: can’t set attribute” will be shown. The guardian assign permission is optional here.

def get_or_create_profile(user):
    profile, created = UserProfile.objects.get_or_create(user=user)
    assign('change_userprofile', user, profile)
    assign('delete_userprofile', user, profile)
    return profile

User.profile = property(get_or_create_profile)
👤Tommy Tang

1đź‘Ť

Here’s a quickie management command that can be used to create default profiles for any users who are lacking them. With this in place you can run ./manage.py missing_profiles at any time, or add it to a cron job, etc.

from django.core.management.base import BaseCommand
from django.contrib.auth.models import User
from people.models import Profile

'''
Create default profiles for any User objects that lack them.
'''


class Command(BaseCommand):
    help = "Create default profiles for any User objects that lack them."

    def handle(self, *args, **options):
        users = User.objects.filter(profile=None)
        for u in users:
            Profile.objects.create(user=u)
            print("Created profile for {u}".format(u=u))
👤shacker

Leave a comment