Django自定义User模型post_save信号不触发无法创建UserProfile
问题原因&解决方案
1. 信号未被正确加载
你将信号导入逻辑写在了UserProfileConfig的ready方法中,但settings.py的INSTALLED_APPS只注册了UsersConfig,没有注册UserProfileConfig,导致ready方法从未执行,信号没有被Django加载。
修复方案:
把信号导入逻辑移到UsersConfig的ready方法中,修改users/apps.py代码如下:
from django.apps import AppConfig class UsersConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'users' def ready(self): import users.signals # 多余的UserProfileConfig可以直接删除,不需要为单个模型单独创建AppConfig
2. 创建UserProfile时字段名错误
你的UserProfiles模型中关联Users的一对一字段变量名为user_id,但信号创建UserProfile时用了不存在的字段名users,会直接触发字段不存在报错,导致创建失败。
修复方案:
修改signals.py中的create_profile方法:
@receiver(post_save, sender=Users) def create_profile(sender, instance, created, **kwargs): if created: # 字段名和模型定义保持一致,使用user_id传参 UserProfiles.objects.create(user_id=instance)
3. 保存用户配置的信号逻辑错误
你的UserProfiles的一对一字段没有配置related_name,默认反向关联名称是userprofiles,不是你写的profile,instance.profile根本不存在,调用save会触发属性不存在报错。另外这个信号逻辑完全冗余,没有修改UserProfile的场景下不需要这个保存逻辑。
修复方案:
直接删除save_user_profile这个信号方法即可。如果后续需要用反向关联调用,也可以给OneToOneField添加related_name参数:
# 修改UserProfiles模型的一对一字段,新增related_name配置 user_id = models.OneToOneField('Users', on_delete=models.CASCADE, db_column='user_id', related_name='profile')
配置后就可以通过instance.profile访问对应用户的配置数据了。
内容的提问来源于stack exchange,提问作者JETHRO KANE
相关产品推荐
相关产品推荐

