У меня есть расширенная модель UserProfile в django:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
#other things in that profile
И signals.py:
from registration.signals import user_registered
from models import UserProfile
from django.contrib.auth.models import User
def createUserProfile(sender, instance, **kwargs):
profile = users.models.UserProfile()
profile.setUser(sender)
profile.save()
user_registered.connect(createUserProfile, sender=User)
Я удостоверяюсь, что сигнал регистрируется при наличии этого в моем __init__.py
:
import signals
Таким образом, это должно создать меня новый UserProfile для каждого пользователя, который регистрируется, правильно? Но это не делает. Я всегда получаю "UserProfile, соответствующий запросу, не существует" ошибки, когда я пытаюсь войти в систему, что означает, что запись базы данных не там.
Я должен сказать, что использую django-регистрацию, которая обеспечивает сигнал user_registered.
Структура важных приложений для этого, что у меня есть одно приложение, названное "пользователями", там я имею: models.py, signals.py, urls.py и views.py (и некоторые другие вещи, которые не должны иметь значения здесь). Класс UserProfile определяется в models.py.
Обновление: Я изменил signals.py на:
from django.db.models.signals import post_save
from models import UserProfile
from django.contrib.auth.models import User
def create_profile(sender, **kw):
user = kw["instance"]
if kw["created"]:
profile = UserProfile()
profile.user = user
profile.save()
post_save.connect(create_profile, sender=User)
Но теперь я получаю "IntegrityError":
"столбец user_id не уникален"
Редактирование 2:
Я нашел его. Похож так или иначе, я зарегистрировал сигнал дважды. Обходное решение для этого описано здесь: http://code.djangoproject.com/wiki/Signals#Helppost_saveseemstobeemittedtwiceforeachsave
Я должен был добавить dispatch_uid, теперь мой signals.py похож на это и работает:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from models import UserProfile
from django.db import models
def create_profile(sender, **kw):
user = kw["instance"]
if kw["created"]:
profile = UserProfile(user=user)
profile.save()
post_save.connect(create_profile, sender=User, dispatch_uid="users-profilecreation-signal")
Вы можете реализовать это с помощью post_save для пользователя:
from django.db.models.signals import post_save
from models import UserProfile
from django.contrib.auth.models import User
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
profile = users.models.UserProfile()
profile.setUser(sender)
profile.save()
post_save.connect(create_profile, sender=User)
Изменить:
Другое возможное решение, которое протестировано и работает (я использую его на своем сайте) :
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
up = UserProfile(user=user, stuff=1, thing=2)
up.save()
post_save.connect(create_profile, sender=User)
Когда вы вызываете profile.setUser ()
, я думаю, вы хотите передать экземпляр
, а не отправителя
в качестве параметра .
Из документации для зарегистрированного пользователем сигнала , отправитель
относится к классу Пользователь
; экземпляр
- это фактический зарегистрированный объект пользователя.