创建扩展的用户配置文件
我在 django 中有一个扩展的 UserProfile 模型:
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-registration,它提供了 user_registered 信号。
为此,重要应用程序的结构是,我有一个名为“users”的应用程序,其中有: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_saveseemstobeemissedtwiceforeachsave
我必须添加一个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")
I have an extended UserProfile model in django:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
#other things in that profile
And a 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)
I make sure the signal gets registered by having this in my __init__.py
:
import signals
So that should create me a new UserProfile for every user that registers, right? But it doesn't. I always get "UserProfile matching query does not exist" errors when I try to log in, which means that the database entry isn't there.
I should say that I use django-registration, which provides the user_registered signal.
The structure of the important apps for this is, that I have one application called "users", there I have: models.py, signals.py, urls.py and views.py (and some other things which shouldn't matter here). The UserProfile class is defined in models.py.
Update: I changed the signals.py to:
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)
But now I get a "IntegrityError":
"column user_id is not unique"
Edit 2:
I found it. Looks like somehow I registred the signal twice. The workaround for this is described here: http://code.djangoproject.com/wiki/Signals#Helppost_saveseemstobeemittedtwiceforeachsave
I had to add a dispatch_uid, now my signals.py looks like this and is working:
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")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以对用户使用 post_save 来实现它:
编辑:
另一种可能的解决方案,经过测试并且有效(我在我的网站上使用它):
You can implement it using post_save on the user:
Edit:
Another possible solution, which is tested and works (I'm using it on my site):
您可以在第一次访问每个用户时创建扩展配置文件:然后
使用
ref: http://www.codekoala.com/blog/2009/quick-django-tip-user-profiles/
You can get the extended profile to be created when first accessed for each user instead:
then use
ref: http://www.codekoala.com/blog/2009/quick-django-tip-user-profiles/
这对我有帮助:primary_key=True
This helped me: primary_key=True
当您调用
profile.setUser()
时,我认为您希望传递instance
而不是sender
作为参数。来自user_registered 信号的文档 ,
sender
指的是User
类;instance
是注册的实际用户对象。When you call
profile.setUser()
, I think you want to passinstance
rather thansender
as the parameter.From the documentation of the user_registered signal,
sender
refers to theUser
class;instance
is the actual user object that was registered.根据我的最新研究,创建一个单独的文件,例如singals.py,是行不通的。
你最好直接将 models.py 中的 'create_profile' 连接到 'post_save' ,否则这段代码将不会被执行,因为它在一个单独的文件中,没有人导入它。
我的最终代码供您参考:
According to my latest research, creating a separate file, e.g., singals.py, does not work.
You'd better connect 'create_profile' to 'post_save' in your models.py directly, otherwise this piece of code won't be executed since it's in a separate file and no one imports it.
My final code for your reference:
2018年更新:
这个问题已经收集了很多观点,也许是时候更新一下了。
这是最新 Django 的最新版本。
Update for 2018:
This question has collected a lot of views, maybe it is time for an update.
This is the latest version for latest Django.