我对extending the existing User
model感兴趣,使用post_save
方法将模型更新为
class LucyGuide(TimeStampedModel):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True)
我关注https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#onetoone,但我的用例存在差异:每个LucyGuide
应该有一个关联的User
,但不是每个User
都是LucyGuide
。
如果我只是简单地转录'这个例子的代码,我相信我的接收器看起来像这样:
@receiver(post_save, sender=User)
def create_user_lucy_guide(sender, instance, created, **kwargs):
if created:
LucyGuide.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_lucy_guide(sender, instance, **kwargs):
instance.lucyguide.save()
但据我所知,第一种方法会使User
成为LucyGuide
,这不是我想要的。此外,第二种方法并不总是有效,因为不是每个User
都有lucyguide
。我会如下修改这个例子吗?
@receiver(post_save, sender=User)
def save_user_lucy_guide(sender, instance, **kwargs):
if hasattr(instance, 'lucyguide'):
instance.lucyguide.save()
更新
特别是,我试图了解如何应用docs中的以下引用:
这些配置文件模型在任何方面都不是特别的 - 它们只是恰好与用户模型具有一对一链接的Django模型。因此,在创建用户时不会自动创建它们,但可以使用
django.db.models.signals.post_save
来创建或更新相关模型。
我注意到这个简单的测试(使用factory_boy
测试装置)已经没有任何post_save
信号传递:
from django.test import TestCase
from lucy_web.test_factories import UserFactory, LucyGuideFactory
class LucyGuideTest(TestCase):
def test_1(self):
user = UserFactory()
lucy_guide = LucyGuideFactory(user=user)
user.first_name = "Andrea"
user.save()
self.assertEqual(lucy_guide.user.first_name, "Andrea")
那么博客文章中第二个post_save
接收者的目的究竟是什么?是否有测试说明这是如何有用的?
答案 0 :(得分:1)
如果您不需要为每个LucyGuide
创建User
,那么您就不需要create_user_lucy_guide
信号。
博客文章说使用了第二个信号,因此您不必致电profile.save()
。它给出的例子是:
def update_profile(request, user_id):
user = User.objects.get(pk=user_id)
user.profile.bio = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit...'
user.save()
我个人不喜欢这样。如果要更新save_user_lucy_guide
,则更明确地删除第二个profile.save()
信号并调用profile
。然后,您不必担心在信号中添加if hasattr(user, lucyguide)
检查,以防止在lucyguide
不存在时出错。