Как получить объекты из двух разных таблиц, которые имеют отношение к третьей таблице, используя связанные имена в Django? - PullRequest
0 голосов
/ 03 апреля 2019

Позвольте мне объяснить.У меня есть 2 таблицы, которые являются дочерними классами другой абстрактной таблицы.Абстрактная таблица имеет отношение к модели под названием Foo.related_name устанавливается динамически.Код выглядит следующим образом:

class Foo(models.Model):
    ...

class Parent(models.Model):
    foo = models.ForeignKey(
        Foo,
        on_delete=models.CASCADE,
        related_name='%(app_label)s_%(class)s_related'
    )
    ...

    def bar(self):
        print('bar')

    class Meta:
        abstract = True

class ChildOne(Parent):
    ...

class ChildTwo(Parent):
    ...

Следовательно, связанные имена становятся 'myapp_childone_related' и 'myapp_childtwo_related'.

Теперь, допустим, я хочу вызвать метод bar() всех объектов модели ChildOne и ChildTwo, связанных с объектом Foo.Однако есть одна загвоздка, которую я хочу получить с помощью метода класса модели Foo.В настоящее время я делаю это следующим образом:

 class Foo(models.Model):
     ...

     def call_bar(self):
         references = ('childone', 'childtwo')
         for ref in references:
             children = getattr(self, f'myapp_{ref}_related').all()
             for child in children:
                 child.bar()

Это прекрасно работает, но, честно говоря, выглядит немного хакерски, особенно когда имеешь дело с более чем двумя детскими классами.Есть ли более приятное, более питонское решение этой проблемы?

Редактировать: Я решил не упоминать ранее, что я хотел вызвать метод bar() из метода класса модели Foo, потому что я думал, что в этом вопросе нет необходимости.Однако в ответе Даниэля Роземана было предложено составить список классов, что является хорошим решением, но оно не будет работать в методе класса, так как классы еще не определены на этом этапе в модуле.Так что упомяну это в этом редакторе.

1 Ответ

1 голос
/ 03 апреля 2019

related_name является только синтаксическим сахаром для выполнения запроса из самого связанного класса.Так что вы должны просто сделать это явно:

child_classes = [ChildOne, ChildTwo]
for child_class in child_classes:
    children = child_class.objects.filter(foo=foo)
...