Оптимизация запросов Django: найти список объектов, основанный на множителях «многие к одному» и «многие ко многим» - PullRequest
1 голос
/ 17 июня 2011

У меня есть уродливая петля, которая работает в Django как пластырь, который я хотел бы оптимизировать для объединения. Я разбил его на основную структуру, чтобы упростить задачу. Я надеюсь, что кто-то еще сталкивался с чем-то подобным - если нет, я поделюсь ответом, когда наконец исправлю это.

Подводя итог

  • Объект A имеет несимметричное отношение «многие ко многим» с самим собой.
  • Объект B имеет отношение многие к одному с Объектом A.
  • Учитывая ObjectB , мне нужен набор других ObjectBs , которые являются потомками ObjectAs , которые связаны с нашими ObjectB's parent ObjectA .

Я уверен, что кто-то с большим опытом работы с базами данных может сформулировать это лучше (оставьте комментарий, если у вас есть лучшее описание этой ассоциации)

Вот простой пример структуры, с которой я работаю в Django, и вида цикла, который выполняется:

class ObjectA(models.Model):
    object_a_rules = models.ManyToManyField("self", symmetrical=False, through='ObjectARule')

class ObjectARule(models.Model):
    object_a_one = models.ForeignKey(ObjectA, related_name="object_a_before")
    object_a_two = models.ForeignKey(ObjectA, related_name="object_a_after")

class ObjectB(models.Model):
    object_a_association = models.ForeignKey(ObjectA)

    def that_annoying_loop_i_mentioned(self):
        object_a_rules_list = ObjectARule.objects.filter(object_a_one = self.object_a_association)
        #A list of all of the ObjectARules that have the ObjectA this ObjectB is associated with
        #as the first half of the many-to-many relationship.

        object_b_list = ObjectB.objects.all()
        #A list of all of the ObjectBs, may also be a filtered list

        for object_a_rule in object_a_rules_list:
            for object_b in object_b_list:
                if (object_a_rule.object_a_two == object_b.object_a_association):
                #if the second half of ObjectARule is the ObjectA of
                #the ObjectB in this list, then do something with that ObjectB.
                pass

Как Django мог получить список ObjectBs через объединение, чтобы не пришлось запускать этот мучительно неэффективный цикл?

1 Ответ

2 голосов
/ 17 июня 2011

Учитывая ObjectB, мне нужен набор другие ObjectBs, которые являются детьми объектов, которые связаны с родительским ObjectA нашего ObjectB.

Если objb - это предоставленный вам объект B, вы можете сделать это следующим образом:

objects = ObjectB.objects.filter(object_a_association__object_a_rules=objb.object_a_association)

или, альтернативно,

objects = ObjectB.objects.filter(object_a_association__object_a_rules__objectb_set=objb)

См. Также Поиск, охватывающий отношения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...