创build扩展的用户configuration文件

我在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 

所以这应该为每个注册的用户创build一个新的UserProfile,对吧? 但事实并非如此。 当我尝试login时,总是得到“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:

我find了。 看起来好像我注册了两次信号。 解决这个问题的方法在这里描述: 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) 

编辑:
另一个可能的解决scheme,这是testing和工作(我在我的网站上使用它):

 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) 

您可以在首次访问每个用户时获取扩展configuration文件:

 from django.db import models from django.contrib.auth.models import User class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) additional_info_field = models.CharField(max_length=50) User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0]) 

然后使用

 from django.contrib.auth.models import User user = User.objects.get(pk=1) user.profile.additional_info_field 

ref: http : //www.codekoala.com/blog/2009/quick-django-tip-user-profiles/

这帮助了我:primary_key = True

 class UserProfile(models.Model): user = models.OneToOneField(User, unique=True, primary_key=True, related_name="user") phone = models.CharField(('phone'),max_length=30, blank=False, null=True) user_building = models.ManyToManyField(Building, blank=True) added_by = models.ForeignKey(User, blank=True, null=True, related_name="added") 

当你调用profile.setUser() ,我想你想传递instance而不是sender作为参数。

从user_registered信号的文档中 , sender指向User类; instance是已注册的实际用户对象。

根据我最近的研究,创build一个单独的文件,例如singals.py不起作用。

你最好直接在你的models.py中将'create_profile'连接到'post_save',否则这段代码不会被执行,因为它是在一个单独的文件中,没有人导入它。

我的最终代码供您参考:

 # models.py # Here goes the definition of class UserProfile. class UserProfile(models.Model): ... # Use signal to automatically create user profile on user creation. # Another implementation: # def create_user_profile(sender, **kwargs): # user = kwargs["instance"] # if kwargs["created"]: # ... def create_user_profile(sender, instance, created, **kwargs): """ :param sender: Class User. :param instance: The user instance. """ if created: # Seems the following also works: # UserProfile.objects.create(user=instance) # TODO: Which is correct or better? profile = UserProfile(user=instance) profile.save() post_save.connect(create_user_profile, sender=User, dispatch_uid="users-profilecreation-signal")