Django создает userprofile, если его не существует
Я использую request.user.get_profile()
в ряде мест в моем коде. Однако не у всех пользователей есть профиль пользователя, связанный с их учетной записью. Есть ли способ создать профиль пользователя автоматически при вызове request.user.get_profile()
, если у них его нет, без необходимости изменять каждый из моих вызовов request.user.get_profile()
. Возможно, используя сигналы или что-то в этом роде.
Проблема заключается в том, что я использую один вход для входа в систему, поэтому, если кто-то войдет в систему в другой системе и затем отправится на мой сайт, они вошли в систему, но не получают созданный профиль пользователя (я создаю профиль пользователя при входе в систему).
Ответы
Ответ 1
Обычно объекты профиля пользователя создаются сразу после создания экземпляра пользователя. Это легко осуществить с помощью сигналов.
Проблема заключается в том, что я использую один вход для входа в систему, поэтому, если кто-то войдет в систему в другой системе и затем отправится на мой сайт, они вошли в систему, но не получают созданный профиль пользователя (я создаю профиль пользователя при входе в систему).
Очевидно, что использование сигналов при создании пользователя не будет работать для вас. Один из способов добиться того, что вы пытаетесь сделать, - заменить вызовы request.user.get_profile()
на пользовательскую функцию. Скажите get_or_create_user_profile(request)
. Эта функция может попытаться получить профиль пользователя, а затем создать его "на лету", если он не существует.
Например,
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
Ответ 2
Я нашел это решение, которое я хотел бы использовать на этом сайте: http://www.turnkeylinux.org/blog/django-profile
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
Использование такого свойства кажется более чистым, чем определение нового метода, но я согласен, что было бы больно проходить через вашу базу кода и изменять user.get_profile()
ссылки на user.profile
.
Опять же, не то, что ваша глобальная функция поиска и замены файлов для?
Ответ 3
На основе ответа bskinner и в ответ на комментарий sqwerty вы можете использовать это:
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)
Таким образом, при необходимости создаст профиль, а User.profile.field = "deep"
будет работать User.profile.save()
.
Ответ 4
Пересмотрено ниже. В противном случае будет показано "AttributeError: невозможно установить атрибут". Предоставление разрешения опекуна необязательно здесь.
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)
Ответ 5
Здесь приведена команда управления quickie, которая может использоваться для создания профилей по умолчанию для любых пользователей, которым их не хватает. При этом вы можете запустить ./manage.py missing_profiles
в любое время или добавить его в задание cron и т.д.
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))