在模型函数中使用django过滤器

时间:2012-10-27 21:30:45

标签: django django-models

模型的主要目的是包含业务逻辑,因此我希望我的大部分代码都以方法的形式存在于django模型中。例如,我想在任务模型中编写一个名为get_tasks_by_user()的方法。所以我可以将其作为

访问
Tasks.get_tasks_by_user(user_id)

以下是我的型号代码:

class Tasks(models.Model):
    slug=models.URLField()
    user=models.ForeignKey(User)
    title=models.CharField(max_length=100)
    objects=SearchManager()
    def __unicode__(self):
        return self.title
    days_passed = property(getDaysPassed)
    def get_tasks_by_user(self,userid):
        return self.filters(user_id=userid)

但这似乎不起作用,我在视图中使用它:

    tasks = Tasks.objects.get_tasks_by_user(user_id)

但它会出现以下错误:

'SearchManager' object has no attribute 'get_tasks_by_user'

如果我删除objects=SearchManager,那么只是错误的经理名称会发生​​变化,所以我认为这不是问题。好像我正在做一些非常基本的错误,请告诉我我做错了什么,我怎么能做我想做的事情。我知道我可以通过Tasks.objects.filters(user_id=userid)做同样的事情,但我想把所有这些逻辑保留在模型中。所以请告诉我们这样做的正确方法。

由于

2 个答案:

答案 0 :(得分:4)

模型类上的任何方法只能用于该模型的实例,即单个对象。

要使get_tasks_by_user功能随时可用(在集合中),需要在model manager上实现。

class TaskManager(models.Manager):
    def get_tasks_by_user(self, user_id):
        return super(TaskManager, self).get_query_set().filter(user=user_id)

class Task(models.Model):
    # ...
    objects = TaskManager()

答案 1 :(得分:3)

一种简单的方法是使用classmethod装饰器使其成为类方法。在class Tasks内:

@classmethod
def get_tasks_by_user(cls, userid):
    return cls.objects.filters(user_id=userid)

这样你就可以直接打电话:

tasks = Tasks.get_tasks_by_user(user_id)

或者,您可以根据Tom的回答使用经理。

要决定在特定情况下选择哪一个,您可以参考James Bennett(Django的发布经理)blog post on when to use managers/classmethod.