24

我在这里关注 Django 文档以实现一个简单的目标:创建新用户后立即创建用户配置文件。

我有一个“帐户”应用程序,我的 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/ 当前事务的 InternalError 是中止,命令被忽略,直到事务块结束

这是回溯错误部分:

/djangoProjects/lwboanova/lwboanova/apps/accounts/models.py in create_user_profile

34: UserProfile.objects.create(user=instance)

这似乎是一个完整性错误,但我没有得到它的原因。

如果你们中的任何一个可以在这方面给我一些帮助,那就太好了。

4

8 回答 8

18

刚刚想通了。

我忘了添加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)

...一切都按预期工作!

为帮助阿什雷干杯^^

于 2012-07-15T03:17:38.763 回答
18

你不应该使用:

user = models.ForeignKey(User, unique=True)

而是使用这个:

from django.conf import settings
..
user = models.OneToOneField(settings.AUTH_USER_MODEL)
于 2014-03-15T02:07:08.483 回答
5

您可以使用 Django Signals 创建它。参考https://docs.djangoproject.com/en/2.2/topics/signals/

将此添加到 settings.py 中的 installed_apps

# settings.py

INSTALLED_APPS = [
    ...
    'accounts.apps.AccountsConfig',
    ...

]

注意:如果你accounts在 INSTALLED_APPS 中使用,你必须在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

于 2019-09-09T20:43:21.820 回答
3
def create_profile(sender,**kwargs ):
    if kwargs['created']:
        user_profile=UserProfile.objects.create(user=kwargs['instance'])


post_save.connect(create_profile,sender=User)

我想这会对你有所帮助。

于 2018-03-07T15:08:32.933 回答
1
@receiver(post_save, sender=User)
 def save_profile(sender, instance, **kwargs):
     instance.profile.save()

像这样它会很容易阅读代码。

于 2019-08-04T18:28:50.053 回答
1
@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()
于 2021-09-15T14:34:31.853 回答
0
    @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)
于 2019-04-08T00:14:02.830 回答
0

我成功尝试了这种方法

def create_profile(sender,**kwargs ):
    if kwargs['created']:
        user_profile=UserProfile(user=kwargs['instance'])
        user_profile.save()

post_save.connect(create_profile, sender=User)
于 2020-07-01T04:58:53.020 回答