首页 > 解决方案 > Django:信号不会自动不为用户创建属性

问题描述

我在创建用户和配置文件时使用 Django 信号时遇到问题。

我正在尝试在创建用户时创建个人资料,但我不断收到错误消息:

AttributeError at /user/create/
'User' object has no attribute 'profile'

所以这是我的User Model

from django.db import models
from django.contrib.auth.models import AbstractUser
from django_countries.fields import CountryField

class User(AbstractUser):
    """auth/login-related fields"""
    is_a = models.BooleanField('a status', default=False)
    is_o = models.BooleanField('o status', default=False)

    def _str_(self):
        return "{} {}".format(self.first_name, self.last_name)

这是我的Profile Model

from django.db import models
from django_countries.fields import CountryField
from django.contrib.auth import get_user_model
User = get_user_model()
from django.db.models.signals import post_save 
from django.dispatch import receiver



class Profile(models.Model):
    """non-auth-related/cosmetic fields"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='Profile')
    birth_date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True)
    nationality = CountryField(null=True)

    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, null=True)

    def __str__(self):
        return f'{self.user.username} Profile'

我的 User Serializer

from rest_framework import serializers
from django.contrib.auth import get_user_model
from ..models.model_user import *

class UserIndexSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = [
            'id',
            'username',
            'password',
            'first_name',
            'last_name',
            'email',
            'is_a',
            'is_o'
        ]

class UserCreateSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = [
            'username',
            'password',
            'first_name',
            'last_name',
            'email',
            'is_a',
            'is_o'
        ]
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User(
            username=validated_data['username'],
            password=validated_data['password'],
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
            email=validated_data['email'],
            is_a=validated_data['is_a'],
            is_o=validated_data['is_o']
            )
        user.set_password(validated_data['password'])
        user.save()
        return user

class UserDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

我的signals.py

from django.db.models.signals import post_save
from django.contrib.auth import get_user_model
User = get_user_model()
from django.dispatch import receiver
from .models.model_profile import *

"""receivers to add a Profile for newly created users"""
@receiver(post_save, sender=User) 
def create_user_profile(sender, instance, created, **kwargs):
  if created:
    Profile.objects.create(user=instance)

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

当我使用 Postman 发布User

{
  "username":"16",
  "password":"12345678",
  "first_name":"Al",
  "last_name":"Pongvf",
  "email":"ahgj@live.fr",
  "is_a":"False",
  "is_o":"False"
}

它给了我这个错误信息:

AttributeError at /user/create/
'User' object has no attribute 'profile'

我一直在寻找解决方案,但我没有幸运:

有谁知道我错过了什么?还是做错了?谢谢!

标签: pythondjangosignals

解决方案


related_name="Profile"Proflile模型上是Profile资本的。您需要用大写字母引用它才能使用它。我建议您将其重命名为小写并进行新的迁移。

例如:

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

但实际上你应该改变这个:

class Profile(models.Model):
    """non-auth-related/cosmetic fields"""
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')

推荐阅读