开发者_如何学GoHow to move stored procedure to django model class and use them in filter/exclude? As said here What is the best way to access stored procedures in Django's ORM it should be possible.
In another word, how can i accomplish something like this:
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)
Not sure why you are referring to stored procedures in this context.
But if i understand your example correct, your problem is that you can filter only by modelfields that have a corresponding field in a database table. And therefore you can't use django's orm to filter by methods and properties.
But you can achieve what you want using a list comprehension:
finished_projects = [p for p in Project.objects.all() if p.is_finished()]
One solution is denormalization:
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)
It is nice if you have much more reads than writes because reads will be very fast (faster than e.g. using stored procedures). But you should take care of consistency yourselves.
Django's aggregates or 'raw' support can be often used to implement stored procedure logic.
精彩评论