Как переместить хранимую процедуру в класс модели django и использовать их в filter / exclude? - PullRequest
0 голосов
/ 06 апреля 2011

Как переместить хранимую процедуру в класс модели django и использовать ее в filter / exclude? Как сказано здесь Каков наилучший способ доступа к хранимым процедурам в ORM Django , это должно быть возможно.

Другими словами, как я могу сделать что-то вроде этого:

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)

Ответы [ 2 ]

1 голос
/ 06 апреля 2011

Не уверен, почему вы ссылаетесь на хранимые процедуры в этом контексте.

Но если я правильно понимаю ваш пример, ваша проблема в том, что вы можете фильтровать только по полям модели, у которых есть соответствующее поле в таблице базы данных. И поэтому вы не можете использовать форму django для фильтрации по методам и свойствам.

Но вы можете достичь того, чего хотите, используя понимание списка:

finished_projects = [p for p in Project.objects.all() if p.is_finished()]
0 голосов
/ 06 апреля 2011
  1. Одним из решений является денормализация:

    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)
    

    Хорошо, если у вас намного больше операций чтения, чем записи, потому что чтение будет очень быстрым (быстрее, например, с использованием хранимых процедур). Но вы должны позаботиться о последовательности сами.

  2. Агрегаты или необработанная поддержка Django часто могут использоваться для реализации логики хранимых процедур.

...