【问题标题】:Signals not works? I want create profile instance when user was created信号不起作用?我想在创建用户时创建配置文件实例
【发布时间】:2026-02-03 07:20:03
【问题描述】:

我阅读了部分文档和一些文章,但我的代码不起作用。

OBS:我正在使用通过 AbstractUser 创建的自定义用户,但我没有添加额外的字段

看看这个例子

profile.signals.py:

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from .models import Profile

User = get_user_model()

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

现在,查看用户创建:

>>> from accounts.models import User
>>> me = User.objects.create(username='myusr', email='me@email.com', password='me123456')
>>> me
<User: myusr>
>>> me.save()
>>> me.profile
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/mnt/sda4/Development/coding/Projects/codesv3/env/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 415, in__get__
    self.related.get_accessor_name()
accounts.models.User.profile.RelatedObjectDoesNotExist: User has no profile.

我不知道怎么了。也因为我之前没用过,对 SQL 触发器一无所知

【问题讨论】:

  • 你在设置中添加了AUTH_USER_MODEL吗?

标签: django


【解决方案1】:

在您的signals.py 文件中,在创建后保存profile,如下所示:

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

确保您在相关的apps.py 文件中import signals 如下示例

from django.apps import AppConfig


class UsersConfig(AppConfig):
    name = 'users'

    def ready(self):
        import users.signals

然后还要确保您进行了以下更改:

您必须将app's config 添加到两个文件之一。

在您的settings.py 文件的INSTALLED_APPS 中,如此链接中所述:Django create profile for user signal

或,

在你相关的app__init__.py文件中,像这样(在这个示例中,相关的应用程序是users):default_app_config = 'users.apps.UsersConfig'

【讨论】:

    【解决方案2】:

    使用refresh_from_db()方法在访问profile对象之前

    >>> from accounts.models import User
    >>> me = User.objects.create(username='myusr', email='me@email.com', password='me123456')
    >>> me
    &ltUser: myusr>
    >>> me.save()
    >>> me.refresh_from_db() # change is here
    >>> me.profile

    【讨论】:

      【解决方案3】:

      首先,该命令创建用户,创建后无需保存:

      me = User.objects.create(username='myusr', email='me@email.com', password='me123456')
      

      其次,您的信号放置在哪里?如果你把它放在模型中,一切都应该有效。 您也可以将其放置在您想要的位置,但您需要将其导入您的应用程序中,如下所示:

      class ProfileConfig(BaseConfig):
          name = ...
          def ready():
              import profiles.signals # where your signals place
      

      【讨论】: