Django - 在用户创建时创建用户配置文件
Posted
技术标签:
【中文标题】Django - 在用户创建时创建用户配置文件【英文标题】:Django - Create user profile on user creation 【发布时间】:2012-07-14 09:29:35 【问题描述】:我正在关注 Django 文档 here 以实现一个简单的目标:创建新用户后立即创建用户配置文件。
我有一个“帐户”应用,我的 accounts.models 如下所示:
# -*- coding: utf-8 -*-
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from main.models import Store
class UserProfile(models.Model):
GENRE_CHOICES = (
('m', 'Masculino'),
('f', 'Feminino'),
)
MARITAL_STATUS_CHOICES = (
('s', 'Solteiro'),
('c', 'Casado'),
('d', 'Divorciado'),
('v', 'Viúvo'),
)
user = models.ForeignKey(User, unique=True)
birth_date = models.DateField()
genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
address = models.CharField(max_length=150)
postal_code_4 = models.PositiveIntegerField()
postal_code_3 = models.PositiveIntegerField()
locatity = models.CharField(max_length=30)
marital_status = models.CharField(max_length=1, choices=MARITAL_STATUS_CHOICES)
child_amount = models.PositiveSmallIntegerField()
is_merchant = models.BooleanField(default=False)
store = models.ForeignKey(Store, null=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
对我来说一切都很好,但是在尝试添加新用户(使用 django admin)时,我没有新创建的用户和用户配置文件,而是收到以下错误: /admin/auth/user/add/ 处的内部错误 当前事务被中止,命令被忽略直到事务块结束
这是回溯错误部分:
/djangoProjects/lwboanova/lwboanova/apps/accounts/models.py in create_user_profile
34: UserProfile.objects.create(user=instance)
这似乎是一个完整性错误,但我不明白它的原因。
如果你们中的任何人能在这方面给我一些帮助,那就太好了。
【问题讨论】:
你安装了 django 工具栏吗?如果是这样,请尝试禁用它,以便获得更好的错误信息。 【参考方案1】:你不应该使用:
user = models.ForeignKey(User, unique=True)
改用这个:
from django.conf import settings
..
user = models.OneToOneField(settings.AUTH_USER_MODEL)
【讨论】:
您对 OneToOneField 的看法是正确的,但与 User 模型的关系很好。也就是说,如果您使用附加字段扩展 User 中的构建。如果您想用自己的用户模型替换内置的用户模型,请仅使用AUTH_USER_MODEL
设置。
@allcaps 最后一句话具有误导性。如果硬编码 User
将来不再是模型,settings.AUTH_USER_MODEL
是一种保护这段代码免受回归错误的方法。【参考方案2】:
刚刚想通了。
我忘记将 null=True
添加到 UserProfile
模型字段的其余部分。
所以accounts.models.UserProfile
字段现在看起来像:
user = models.ForeignKey(User, unique=True)
birth_date = models.DateField(null=True)
genre = models.CharField(max_length=1, choices=GENRE_CHOICES, null=True)
address = models.CharField(max_length=150, null=True)
postal_code_4 = models.PositiveIntegerField(null=True)
postal_code_3 = models.PositiveIntegerField(null=True)
locatity = models.CharField(max_length=30, null=True)
marital_status = models.CharField(max_length=1, choices=MARITAL_STATUS_CHOICES, null=True)
child_amount = models.PositiveSmallIntegerField(null=True)
is_merchant = models.BooleanField(default=False)
store = models.ForeignKey(Store, null=True)
...一切都按预期进行!
为尝试帮助阿什雷干杯^^
【讨论】:
,请您检查并指导我,所以问题***.com/questions/17806683/… 嗨,你能发布一下你的views.py文件是什么样子的吗?【参考方案3】:您可以使用 Django 信号来创建它。参考https://docs.djangoproject.com/en/2.2/topics/signals/
将此添加到 settings.py 中的 installed_apps
# settings.py
INSTALLED_APPS = [
...
'accounts.apps.AccountsConfig',
...
]
注意:如果您在 INSTALLED_APPS 中使用accounts
,则必须在 init.py
在 models.py 中删除 create_user_profile
# models.py
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from main.models import Store
class UserProfile(models.Model):
GENRE_CHOICES = (
('m', 'Masculino'),
('f', 'Feminino'),
)
MARITAL_STATUS_CHOICES = (
('s', 'Solteiro'),
('c', 'Casado'),
('d', 'Divorciado'),
('v', 'Viúvo'),
)
user = models.OneToOneField(User)
birth_date = models.DateField()
genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
address = models.CharField(max_length=150)
postal_code_4 = models.PositiveIntegerField()
postal_code_3 = models.PositiveIntegerField()
locatity = models.CharField(max_length=30)
marital_status = models.CharField(max_length=1, choices=MARITAL_STATUS_CHOICES)
child_amount = models.PositiveSmallIntegerField()
is_merchant = models.BooleanField(default=False)
store = models.ForeignKey(Store, null=True)
在signals.py中添加create_user_profile
# signals.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import UserProfile
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
最后,编辑apps.py
# apps.py
from django.apps import AppConfig
class AccountsConfig(AppConfig):
name = 'accounts'
def ready(self):
import accounts.signals
【讨论】:
我喜欢这个答案,它应该标记为已解决。谢谢! 第三个代码块的结尾应该是instance.userprofile.save()
吗?我遇到了一个奇怪的问题,我的 .profile
(或 .userprofile
,实际上)版本导致 AttributeError。【参考方案4】:
def create_profile(sender,**kwargs ):
if kwargs['created']:
user_profile=UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile,sender=User)
我想这会对你有所帮助。
【讨论】:
这需要更多关于它为什么有用的细节。【参考方案5】:@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
这样就很容易阅读代码了。
【讨论】:
您能否为这个答案添加一些解释,使这个答案与众不同?【参考方案6】:@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
【讨论】:
【参考方案7】: @receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if kwargs.get('created', True) and not kwargs.get('raw', False):
Profile.objects.create(user=instance)
【讨论】:
感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation 将通过展示为什么这是解决问题的好方法,并使其对有其他类似问题的未来读者更有用,从而大大提高其长期价值。请edit您的回答添加一些解释,包括您所做的假设。【参考方案8】:我试过这个方法成功了
def create_profile(sender,**kwargs ):
if kwargs['created']:
user_profile=UserProfile(user=kwargs['instance'])
user_profile.save()
post_save.connect(create_profile, sender=User)
【讨论】:
以上是关于Django - 在用户创建时创建用户配置文件的主要内容,如果未能解决你的问题,请参考以下文章
创建配置文件时,django social auth 不返回 first_name 和 last_name - django 1.5
我一直在/ admin / login /获取RelatedObjectDoesNotExist。如何通过一对一关系在Django中成功创建用户配置文件?