在Django自定义管理器类中使用另一个模型管理器的代码

时间:2012-04-06 11:45:33

标签: django django-orm django-managers

我有两个模型,比如QuestionTopic

我正在尝试向问题模型的自定义管理器添加方法,例如一种按Topic过滤的方法。

我似乎无法使用其他经理的代码(也不能import Topic,所以我不能Topic.objects...

class QuestionManager

def my_feed(self, user):
       topics = TopicManager().filter(user=user) # 1st approach
       #topics = Topic.objects.filter(user=user) # 2nd line
       # do something with topics

类TopicManager      ....

使用第一种方法,我收到以下错误:

virtualenv/local/lib/python2.7/site-packages/django/db/models/sql/query.pyc in get_meta(self)
    219         by subclasses.
    220         """
--> 221         return self.model._meta
    222 
    223     def clone(self, klass=None, memo=None, **kwargs):

AttributeError: 'NoneType' object has no attribute '_meta'

我无法使用第二行,因为我无法导入主题,因为主题依赖于此文件中的TopicManager。有解决方法吗?

2 个答案:

答案 0 :(得分:3)

在任何情况下,您都不能直接使用经理。您始终可以通过模型类访问它。

如果由于循环依赖性而无法在模板顶部导入模型,则只需在方法内导入即可。

答案 1 :(得分:0)

您应该可以将其放在 managers.py 模块的底部:

# Prevent circular import error between models.py and managers.py
from apps.drs import models

在您的管理器类中,您可以使用 models.<modelname> 引用其他模型,这应该可以工作,避免循环导入。

例如:

class QuestionManager(Manager):

    def my_feed(self, user):
        topics = models.Topic.objects.filter(user=user)
        # do something with topics

# Prevent circular import error between models.py and managers.py
from apps.drs import models

这是有效的,因为您导入的是模块,而不是模型类,这会导致延迟导入。当函数运行时,模块将被导入并且一切正常。

您还可以使用 django.apps.get_model() 按名称加载模型:

from django.apps import apps
apps.get_model('my_app', 'MyModel')

详情here

例如:

from django.apps import apps

class QuestionManager(Manager):

    def my_feed(self, user):
        topics = apps.get_model('my_app', 'Topic').objects.filter(user=user)
        # do something with topics