在保存 Django 模型时如何避免递归
How can I avoid recursion during saving of django model
我有模型Entry
现在,无论何时为任何日期创建 Entry
。然后在保存之前我需要进行检查并添加更多条目,例如
Entry 1 - red
现在假设如果有 entry.color = red
那么我还需要再输入两个条目,例如
Entry 2 - red2
Entry 3 - red3
现在我把它放在 pre_save 信号中
@receiver(pre_save, sender=Entry)
def new_entries(sender, instance, *args, **kwargs):
pass
现在我的问题是这以无限递归结束,因为我想保存的那些新条目也发送 pre_save 信号并且这个循环永远不会结束。
该逻辑放在哪里才不会发生递归?
我认为你应该有 2 个独立的模型。您的 'parent' Entry
可以是主要 Entry
模型的子类,因此只有 IT 可以创建新的子条目。
class Entry(models.Model):
pass
# whatever you need here
class ParentEntry(Entry):
@receiver(pre_save, sender=ParentEntry)
def new_entries(sender, instance, *args, **kwargs):
pass
添加另一个模型的原因是这些模型实际上做了 2 件不同的事情,1 创建时创建更多,1 不创建。为了清楚起见,我会防止 1 个模型的构造函数可以做 2 个独立的事情的情况。
像这样的东西应该可以工作:
class Entry(model.Model):
def save(self, color, create_more=True, *args, **kwargs):
if self.pk is None: # this is a new Entry
if create_more:
new_color = '%s2' % color
Entry(color=new_color, create_more=False).save()
super(Entry, self).save(...)
虽然我怀疑有更好的方法,但如果不知道您正在尝试做的事情的更多细节,我不能说。
我会用一个额外的参数来解决它,而不是附加到 pre_save:
import django.db.models
class Entry(models.Model):
color=models.CharField(max_length="50")
def save(self,create_children=True,**kwargs):
if create_children and not self.pk:
result = super(Entry,self).save(**kwargs)
Entry(color=self.color).save(create_children=False)
Entry(color=self.color).save(create_children=False)
else:
result = super(Entry,self).save(**kwargs)
return result
您要确保在实际构造子项之前调用 super(Entry,self).save(**kwargs)
,否则当 super() 引发 IntegrityError
时,您会用模型弄乱数据库
在post_save django 信号中避免递归'if created' 需要检查
from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender=DemoModel)
def _post_save_receiver(sender,instance,created, **kwargs):
if created:
print('hi..')
instance.save()
我有模型Entry
现在,无论何时为任何日期创建 Entry
。然后在保存之前我需要进行检查并添加更多条目,例如
Entry 1 - red
现在假设如果有 entry.color = red
那么我还需要再输入两个条目,例如
Entry 2 - red2
Entry 3 - red3
现在我把它放在 pre_save 信号中
@receiver(pre_save, sender=Entry)
def new_entries(sender, instance, *args, **kwargs):
pass
现在我的问题是这以无限递归结束,因为我想保存的那些新条目也发送 pre_save 信号并且这个循环永远不会结束。
该逻辑放在哪里才不会发生递归?
我认为你应该有 2 个独立的模型。您的 'parent' Entry
可以是主要 Entry
模型的子类,因此只有 IT 可以创建新的子条目。
class Entry(models.Model):
pass
# whatever you need here
class ParentEntry(Entry):
@receiver(pre_save, sender=ParentEntry)
def new_entries(sender, instance, *args, **kwargs):
pass
添加另一个模型的原因是这些模型实际上做了 2 件不同的事情,1 创建时创建更多,1 不创建。为了清楚起见,我会防止 1 个模型的构造函数可以做 2 个独立的事情的情况。
像这样的东西应该可以工作:
class Entry(model.Model):
def save(self, color, create_more=True, *args, **kwargs):
if self.pk is None: # this is a new Entry
if create_more:
new_color = '%s2' % color
Entry(color=new_color, create_more=False).save()
super(Entry, self).save(...)
虽然我怀疑有更好的方法,但如果不知道您正在尝试做的事情的更多细节,我不能说。
我会用一个额外的参数来解决它,而不是附加到 pre_save:
import django.db.models
class Entry(models.Model):
color=models.CharField(max_length="50")
def save(self,create_children=True,**kwargs):
if create_children and not self.pk:
result = super(Entry,self).save(**kwargs)
Entry(color=self.color).save(create_children=False)
Entry(color=self.color).save(create_children=False)
else:
result = super(Entry,self).save(**kwargs)
return result
您要确保在实际构造子项之前调用 super(Entry,self).save(**kwargs)
,否则当 super() 引发 IntegrityError
在post_save django 信号中避免递归'if created' 需要检查
from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender=DemoModel)
def _post_save_receiver(sender,instance,created, **kwargs):
if created:
print('hi..')
instance.save()