避免Django应用程序中的循环模型导入

时间:2011-08-03 07:29:20

标签: python django organization circular-reference contenttype

我有一个django项目,有2个这样的应用程序:

## 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已导入到项目应用中。

但是,我想在标签应用中访问此方法,但这样做会导致循环导入。

现在我在标签应用程序中获取带有一组标签的所有项目的解决方法是在多对多字段中的反向关系上进行集合交集。

## 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())

这会导致多个查询和一组交集。有没有办法在标签应用程序中使用Tag模型执行Item.objects.filter(tags=t1).filter(tags=t2)...之类的操作?

我能够使用contenttypes解决此问题,以使Item模型进行相同的查询。这是可以接受的,还是有更好的方法来组织这段代码?

1 个答案:

答案 0 :(得分:24)

使用外键定义模型时,可以使用以下格式:

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

这意味着您不需要导入Tag类,只需安装标签app。

然后,您可以将函数存储在不同的位置,可能同时导入Tag和Item,而不必担心循环导入。