模型的主要目的是包含业务逻辑,因此我希望我的大部分代码都以方法的形式存在于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)
做同样的事情,但我想把所有这些逻辑保留在模型中。所以请告诉我们这样做的正确方法。
由于
答案 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.