Django - Create user profile on user creation

六月ゝ 毕业季﹏ 提交于 2019-11-27 03:09:01

问题


I'm following Django documentation here in order to achieve a simple objective: Create a user profile as soon as a new user is created.

I have an 'accounts' app and my accounts.models looks like this:

# -*- 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)

Everything looks fine to me but when trying to add a new user (using django admin), instead of having a newly created user and user profile, I get the following error: InternalError at /admin/auth/user/add/ current transaction is aborted, commands ignored until end of transaction block

Here is the traceback error part:

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

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

It seems like an integrity error but I'm not getting the reason for it.

Would be great if any of ya could give me some help on this.


回答1:


Just figured it out.

I forgot to add null=True to the rest of UserProfile model fields.

So the accounts.models.UserProfile fields now looks like:

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)

...and everything is working as intended!

Cheers for trying to help Ashray ^^




回答2:


You shouldn't use:

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

Instead use this:

from django.conf import settings
..
user = models.OneToOneField(settings.AUTH_USER_MODEL)



回答3:


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


post_save.connect(create_profile,sender=User)

I think this will help you.




回答4:


    @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)



回答5:


@receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): instance.profile.save()




回答6:


You can create this using Django Signals. Reference https://docs.djangoproject.com/en/2.2/topics/signals/

Add this to installed_apps in settings.py

# settings.py

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

]

Note: if you use accounts in INSTALLED_APPS, you'll have to initialise in init.py

In models.py remove 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)

Add create_user_profile in signals.py

# 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()

Finally, edit apps.py

# apps.py

from django.apps import AppConfig

class AccountsConfig(AppConfig):
    name = 'accounts'

    def ready(self):
        import accounts.signals



来源:https://stackoverflow.com/questions/11488974/django-create-user-profile-on-user-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!