如何防止灯具与 django post_save 信号代码冲突?
在我的应用程序中,我想在新用户注册时在某些表中创建条目。例如,我想创建一个用户配置文件,然后该配置文件将引用他们的公司和他们的一些其他记录。我用 post_save 信号实现了这一点:
def callback_create_profile(sender, **kwargs):
# check if we are creating a new User
if kwargs.get('created', True):
user = kwargs.get('instance')
company = Company.objects.create(name="My Company")
employee = Employee.objects.create(company=company, name_first=user.first_name, name_last=user.last_name)
profile = UserProfile.objects.create(user=user, employee=employee, partner=partner)
# Register the callback
post_save.connect(callback_create_profile, sender=User, dispatch_uid="core.models")
这在运行时效果很好。我可以使用管理员创建一个新用户,其他三个表也可以获取合理的条目。 (除此之外,由于 user.first_name 和 user.last_name 在保存时没有在管理员表单中填写,因此我仍然不明白为什么这样做)
问题出现在我运行测试时套房。在此之前,我创建了一堆固定装置来在表中创建这些条目。现在我收到一个错误,指出:
IntegrityError: duplicate key value violates unique constraint "core_userprofile_user_id_key"
我认为这是因为我已经在 ID 为“1”的装置中创建了一家公司、员工和个人资料记录,现在 post_save 信号正在尝试重新创建它。
我的问题是:运行灯具时可以禁用此 post_save 信号吗?我可以检测到我正在作为测试套件的一部分运行而不创建这些记录吗?我现在应该从灯具中删除这些记录吗(尽管信号仅设置默认值而不是我想要测试的值)?为什么夹具加载代码不覆盖创建的记录?
人们如何做到这一点?
In my application, I want to create entries in certain tables when a new user signs up. For instance, I want to create a userprofile which will then reference their company and some other records for them. I implemented this with a post_save signal:
def callback_create_profile(sender, **kwargs):
# check if we are creating a new User
if kwargs.get('created', True):
user = kwargs.get('instance')
company = Company.objects.create(name="My Company")
employee = Employee.objects.create(company=company, name_first=user.first_name, name_last=user.last_name)
profile = UserProfile.objects.create(user=user, employee=employee, partner=partner)
# Register the callback
post_save.connect(callback_create_profile, sender=User, dispatch_uid="core.models")
This works well when run. I can use the admin to create a new user and the other three tables get entries with sensible as well. (Except that is, the employee since the user.first_name and user.last_name aren't filled out in the admin's form when it saves. I still don't understand why it is done like that)
The problem came when I ran my test suite. Before this, I had created a bunch of fixtures to create these entries in the tables. Now I get an error that states:
IntegrityError: duplicate key value violates unique constraint "core_userprofile_user_id_key"
I think this is because I have already created a company,employee and profile records in the fixture with id "1" and now the post_save signal is trying to recreate it.
My questios are: can I disable this post_save signal when running fixtures? Can I detect that I am running as part of the test suite and not create these records? Should I delete these records from the fixtures now (although the signal only sets defaults not the values I want to be testing against)? Why doesn't the fixture loading code just overwrite the created records?
How do people do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想我找到了一种方法来做到这一点。与信号一起传入的 kwargs 中有一个“raw”参数,因此我可以用以下参数替换上面的测试:
在 loaddata 运行时使用 Raw。这似乎可以解决问题。
这里提到: http://code.djangoproject.com/ticket/13299
将是如果有记录就好了: http:// /docs.djangoproject.com/en/stable/ref/signals/#django.db.models.signals.post_save
I think I figured out a way to do this. There is a 'raw' parameter in the kwargs passed in along with signals so I can replace my test above with this one:
Raw is used when loaddata is running. This seems to do the trick.
It is mentioned here: http://code.djangoproject.com/ticket/13299
Would be nice if this was documented: http://docs.djangoproject.com/en/stable/ref/signals/#django.db.models.signals.post_save
这是一个老问题,但我发现最简单的解决方案是使用由加载数据传递的“原始”参数,并装饰侦听器函数,例如:
然后
This is an old question, but the solution I've found most straightforward is to use the 'raw' argument, passed by load data, and decorate the listener functions, for example:
and then
简单的解决方案,将其添加到 post_save 函数的开头:
这将导致该函数在加载夹具时退出。
请参阅: https://docs.djangoproject.com/en/dev/参考/信号/#post-save
Simple solution, add this to the beginning of your post_save function:
This will cause this function to exit when loading a fixture.
See: https://docs.djangoproject.com/en/dev/ref/signals/#post-save
我在我的一个项目中遇到了类似的问题。就我而言,信号也减慢了测试速度。我最终放弃了信号,转而重写
Model.save()
方法。但就您而言,我认为通过重写任何
save()
方法来实现此目的没有意义。在这种情况下,您可能想尝试一下。警告,我只尝试过一次。它似乎有效,但尚未经过彻底测试。User
类的post_save
信号的callback_create_profile
函数。I faced a similar problem in one of my projects. In my case the signals were slowing down the tests as well. I ended up abandoning signals in favour of overriding a
Model.save()
method instead.In your case however I don't think it makes sense to achieve this by overriding any
save()
methods. In that case you might want to try this. Warning, I only tried it once. It seemed to work but is not thoroughly tested.callback_create_profile
function from theUser
class'post_save
signal.