背景:
我有具有属性is_obsolete (默认设置为False)的标记模型。
class Tag(model.Model):
...
is_obsolete = False我有StatusInfo模型,它有一个外键可以通过"affected_tag“标记。
class StatusInfo(models.Model):
...
affected_tag = ForeignKey(Tag)当创建StatusInfo实例时,它们会触发pre_save()信号以更改<StatusInfo>.affected_tag.is_obsolete=True
@receiver(pre_save, sender=StatusInfo)
def status_change_modification(sender, instance, *args, **kwargs):
"""
Changes tags and concepts to be obsolete or deprecated.
if a tag is obsolete or deprecated, all of the tag's concepts are obsolete or deprecated
"""
assert hasattr(instance.affected_tag, "id")
# set up variables
kwargs = {}
if instance.status == "d":
kwargs["is_deprecated"] = True
elif instance.status == "o":
kwargs["is_obsolete"] = True
inner_tag_status_change(instance, **kwargs)
def inner_tag_status_change(instance, **kwargs):
"""
update the is_updated fields for status_info
kwargs is either:
kwargs = {'is_obsolete': True} # or {'is_deprecated': True}
"""
affected = Tag.objects.filter(id=instance.affected_tag.id).first()
affected.__dict__.update(**kwargs)
affected.save(update_fields=list(kwargs.keys()))问题
我不明白的是,为什么当它到达测试的底部时,我仍然有标记实例self.soon_to_be_obsolete_tag.is_obsolete == False
我尝试过.update(**kwargs)和.save(updated_fields=list(kwargs.keys()))在inner_tag_status_change()中,但是它没有保存更改--在调试模式中执行它时,它看起来很好--然后返回到测试的最后一行。我是在处理一个单独的副本,还是在缓存我应该检查的东西?
在测试/测试状态模型. in中
def test_status_set_tag_info_obsolete(self):
""" check to see if the creation of a statusInfo
object which runs a pre_save signal changes
the soon_to_be_obsolete_tag to is_obsolete=True
"""
self.assertFalse(self.soon_to_be_obsolete_tag.is_obsolete)
self.main_status_info = StatusInfoFactory(
affected_tag=self.soon_to_be_obsolete_tag,
status="o", # obsolete
by=self.new_replacement_tag,
)
self.assertTrue(self.soon_to_be_obsolete_tag.is_obsolete) # still False发布于 2022-06-13 20:31:12
根据您的测试和预保存逻辑,看起来您正在更新数据库中的标记,但是Django对附加到模型的标记对象的缓存没有更新。
因此,我认为问题在于,在status_change_modification和inner_tag_status_change中,您都访问了instance.affected_tag,但没有直接更新instance.affected_tag。相反,您使用一个额外的查询从数据库中抓取该标记,然后保存它。
我猜如果你把你的测试更新到这个,它就会起作用:
self.assertTrue(Tag.objects.get(id=self.soon_to_be_obsolete_tag).is_obsolete)或者,如果您使用refresh_from_db强制对self.soon_to_be_obsolete_tag进行刷新,那么这也应该是有效的:
self.soon_to_be_obsolete_tag.refresh_from_db()
self.assertTrue(self.soon_to_be_obsolete_tag.is_obsolete)您还可以考虑更新您的inner_tag_status_change逻辑,以直接更新标记(我不确定这是否会解决您正在经历的问题,但它将删除可能不需要的额外SELECT查询):
def inner_tag_status_change(instance, **kwargs):
instance.affected_tag.__dict__.update(**kwargs)
instance.affected_tag.save(update_fields=list(kwargs.keys()))https://stackoverflow.com/questions/72583034
复制相似问题