Django 管理父模型的状态,基于 "child models"(对父模型有 fk 的模型)
Django managing state of a parent model, based on "child models" (models that have a fk to the parent model)
设计一个系统,该系统需要一个模型的状态转换基于其他模型的转换。
我正在使用 Django FSM
示例:
class Foo(models.Model):
baz = models.Charfield()
state = FSMField(default='new')
class Bar(models.Model):
x = models.CharField()
state = FSMField(default='draft')
foo = models.ForeignKey(Foo)
用例:
Foo 可以有以下状态 - 新建、草稿、完成、pending_approval、已批准
Foo 可以有多个 Bars
栏可以有以下状态 - 草稿、完成
当所有 Bar 都完成时,Foo 应该自动完成,如何实现
取决于用例,但您可以通过以下方式执行此操作:
每次任何 Bar 完成时,您检查它的 Foo
对象是否已完成所有 Bar
。
class Bar(models.Model):
x = models.CharField()
state = FSMField(default='draft')
foo = models.ForeignKey(Foo)
def save(self,*args,**kwargs):
if not self.foo.bar_set.exclude(state='complete'):
self.foo.state = 'complete'
self.foo.save()
super().save(*args,**kwargs)
我根本不知道 django-fsm,但快速浏览一下文档,有一个 post_transition
signal 在实例更改其状态后触发。因此,您可以定义一个监听 Bar 的对象,然后检查实例的 Foo 对象是否只完成了 Bars。类似于:
@receiver(post_transition, sender=Bar)
def check_completed(sender, instance, name, source, target):
if target == 'completed':
if not instance.foo.bar_set.filter(state='draft').exists():
instance.foo.state = 'completed'
instance.foo.save()
设计一个系统,该系统需要一个模型的状态转换基于其他模型的转换。
我正在使用 Django FSM
示例:
class Foo(models.Model):
baz = models.Charfield()
state = FSMField(default='new')
class Bar(models.Model):
x = models.CharField()
state = FSMField(default='draft')
foo = models.ForeignKey(Foo)
用例:
Foo 可以有以下状态 - 新建、草稿、完成、pending_approval、已批准 Foo 可以有多个 Bars
栏可以有以下状态 - 草稿、完成
当所有 Bar 都完成时,Foo 应该自动完成,如何实现
取决于用例,但您可以通过以下方式执行此操作:
每次任何 Bar 完成时,您检查它的 Foo
对象是否已完成所有 Bar
。
class Bar(models.Model):
x = models.CharField()
state = FSMField(default='draft')
foo = models.ForeignKey(Foo)
def save(self,*args,**kwargs):
if not self.foo.bar_set.exclude(state='complete'):
self.foo.state = 'complete'
self.foo.save()
super().save(*args,**kwargs)
我根本不知道 django-fsm,但快速浏览一下文档,有一个 post_transition
signal 在实例更改其状态后触发。因此,您可以定义一个监听 Bar 的对象,然后检查实例的 Foo 对象是否只完成了 Bars。类似于:
@receiver(post_transition, sender=Bar)
def check_completed(sender, instance, name, source, target):
if target == 'completed':
if not instance.foo.bar_set.filter(state='draft').exists():
instance.foo.state = 'completed'
instance.foo.save()