【问题标题】:How to move stored procedure to django model class and use them in filter/exclude?如何将存储过程移动到 django 模型类并在过滤器/排除中使用它们?
【发布时间】:2011-07-30 18:31:21
【问题描述】:
如何将存储过程移动到 django 模型类并在过滤/排除中使用它们?
正如这里所说的What is the best way to access stored procedures in Django's ORM 应该是可能的。
换句话说,我怎样才能完成这样的事情:
class Project(models.Model):
name = models.CharField()
def is_finished(self):
count = self.task_set.all().count()
count2 = self.task_set.filter(finished=True).count()
if count == count2:
return True
else:
return False
class Task(models.Model):
name = models.CharField()
finished = models.BooleanField()
project = models.ForeignKey(Project)
#somewhere else in the code...
finished_projects = Project.objects.filter(is_finished=True)
【问题讨论】:
标签:
python
django
stored-procedures
django-models
【解决方案1】:
不确定您为什么在这种情况下指代存储过程。
但如果我理解您的示例正确,您的问题是您只能通过在数据库表中具有相应字段的模型字段进行过滤。
因此,您不能使用 django 的 orm 来按方法和属性进行过滤。
但是您可以使用列表推导来实现您想要的:
finished_projects = [p for p in Project.objects.all() if p.is_finished()]
【解决方案2】:
-
一种解决方案是非规范化:
class Project(models.Model):
name = models.CharField()
is_finished = models.BooleanField()
def _is_finished(self):
return self.task_set.exclude(finished=True).exists()
def update_finished(self):
self.is_finished = self._is_finished()
self.save()
class Task(models.Model):
name = models.CharField()
finished = models.BooleanField()
project = models.ForeignKey(Project)
def save(*args, **kwargs):
res = super(Task, self).save(*args, **kwargs)
self.project.update_finished()
return res
#somewhere else in the code...
finished_projects = Project.objects.filter(is_finished=True)
如果您的读取比写入多得多,那就太好了,因为读取会非常快(比例如使用存储过程更快)。但是您应该自己注意一致性。
Django 的聚合或“原始”支持通常可用于实现存储过程逻辑。