Django - 在用户创建时创建用户配置文件

Lim*_*aaf 20 django user-profile django-registration

我在这里关注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)
Run Code Online (Sandbox Code Playgroud)

一切看起来都不错,但在尝试添加新用户(使用django admin)时,而不是新创建的用户和用户配置文件,我收到以下错误: / admin/auth/user/add/current transaction中的InternalError是中止,命令被忽略,直到事务块结束

这是回溯错误部分:

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

34: UserProfile.objects.create(user=instance)
Run Code Online (Sandbox Code Playgroud)

这似乎是一个完整性错误,但我没有得到它的理由.

如果有任何一个可以给我一些帮助,那将是很好的.

Lim*_*aaf 16

刚想通了.

我忘了添加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)
Run Code Online (Sandbox Code Playgroud)

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

干杯试图帮助Ashray ^^


小智 14

你不应该使用:

user = models.ForeignKey(User, unique=True)
Run Code Online (Sandbox Code Playgroud)

而是使用这个:

from django.conf import settings
..
user = models.OneToOneField(settings.AUTH_USER_MODEL)
Run Code Online (Sandbox Code Playgroud)

  • @allcaps最后一句是误导性的.如果硬编码的"用户"不再是未来的模型,`settings.AUTH_USER_MODEL`是一种保护这段代码免受回归错误的方法. (3认同)

ari*_*ari 6

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

\n\n

将其添加到settings.py中的installed_apps中

\n\n
# settings.py\n\nINSTALLED_APPS = [\n    ...\n    \'accounts.apps.AccountsConfig\',\n    ...\n\n]\n
Run Code Online (Sandbox Code Playgroud)\n\n

注意:如果您accounts在 INSTALLED_APPS 中使用,则必须在init .py中初始化

\n\n

在 models.py 中删除 create_user_profile

\n\n
# models.py\n\nfrom django.db import models\nfrom django.db.models.signals import post_save\nfrom django.contrib.auth.models import User\nfrom main.models import Store\n\nclass UserProfile(models.Model):\n\n    GENRE_CHOICES = (\n        (\'m\', \'Masculino\'),\n        (\'f\', \'Feminino\'),\n    )\n    MARITAL_STATUS_CHOICES = (\n        (\'s\', \'Solteiro\'),\n        (\'c\', \'Casado\'),\n        (\'d\', \'Divorciado\'),\n        (\'v\', \'Vi\xc3\xbavo\'),\n    )\n\n    user = models.OneToOneField(User)\n    birth_date = models.DateField()\n    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)\n    address = models.CharField(max_length=150)\n    postal_code_4 = models.PositiveIntegerField()\n    postal_code_3 = models.PositiveIntegerField()\n    locatity = models.CharField(max_length=30)\n    marital_status = models.CharField(max_length=1, choices=MARITAL_STATUS_CHOICES)\n    child_amount = models.PositiveSmallIntegerField()\n    is_merchant = models.BooleanField(default=False)\n    store = models.ForeignKey(Store, null=True)\n
Run Code Online (Sandbox Code Playgroud)\n\n

在signals.py中添加create_user_profile

\n\n
# signals.py\n\nfrom django.contrib.auth.models import User\nfrom django.db.models.signals import post_save\nfrom django.dispatch import receiver\nfrom .models import UserProfile\n\n@receiver(post_save, sender=User)\ndef create_user_profile(sender, instance, created, **kwargs):\n    if created:\n        UserProfile.objects.create(user=instance)\n\n\n@receiver(post_save, sender=User)\ndef save_user_profile(sender, instance, **kwargs):\n    instance.profile.save()\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,编辑apps.py

\n\n
# apps.py\n\nfrom django.apps import AppConfig\n\nclass AccountsConfig(AppConfig):\n    name = \'accounts\'\n\n    def ready(self):\n        import accounts.signals\n\n
Run Code Online (Sandbox Code Playgroud)\n