Избегайте импорта кольцевых моделей в приложениях Django - PullRequest
8 голосов
/ 03 августа 2011

У меня есть проект django с двумя приложениями, подобными этим:

## tags app, models.py
class Tag(models.Model):
    title = models.CharField(max_length=50)


## items app, models.py
from application.tags.models import Tag

class Item(models.Model):
    title = models.CharField(max_length=300)
    tags = models.ManyToManyField(Tag, related_name="items")

ОБНОВЛЕНИЕ, ЧТОБЫ УТОЧНИТЬ РАСПОЛОЖЕНИЕ ФУНКЦИЙ

У меня есть метод другой модели в items.models, который получает все элементы, имеющие набор тегов.

Полученный запрос выглядит так:

## Gets all of the items that have tags t1 and t2
Item.objects.filter(tags=t1).filter(tags=t2)

Этот метод использует модель Item, а также модель Tag, что нормально, поскольку Tag импортируется в приложение items.

Однако я хочу иметь доступ к этому методу в приложении тегов, но это приведет к циклическому импорту.

Прямо сейчас мой обходной путь для получения всех элементов с набором тегов в приложении тегов - это пересечение наборов по обратному отношению в поле «многие ко многим».

## Get all items that have the tags with ids tag_ids
item_set = set(Tag.objects.get(pk=tag_ids[0]).items.all())
for cur_tag_id in tag_ids[1:]: ## for all of the rest of the tags
     item_set = item_set & set(Tag.objects.get(pk=cur_tag_id).items.all())

Это приводит к еще нескольким запросам и пересечению множества. Есть ли способ сделать что-то вроде Item.objects.filter(tags=t1).filter(tags=t2)... из модели Tag в приложении тегов?

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

1 Ответ

24 голосов
/ 03 августа 2011

Когда вы определяете модели с внешними ключами, вы можете использовать формат:

tags = models.ManyToManyField('tags.Tag', ...)

Это означает, что вам не нужно импортировать класс Tag, просто установите приложение тегов.1005 * Затем вы можете сохранить функцию в другом месте, которая может импортировать тег и элемент, и вам не придется беспокоиться о циклическом импорте.

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