【发布时间】:2011-01-10 21:54:38
【问题描述】:
我正在尝试找到一种方法来实现自定义 QuerySet 和自定义 Manager 而不会破坏 DRY。这是我目前所拥有的:
class MyInquiryManager(models.Manager):
def for_user(self, user):
return self.get_query_set().filter(
Q(assigned_to_user=user) |
Q(assigned_to_group__in=user.groups.all())
)
class Inquiry(models.Model):
ts = models.DateTimeField(auto_now_add=True)
status = models.ForeignKey(InquiryStatus)
assigned_to_user = models.ForeignKey(User, blank=True, null=True)
assigned_to_group = models.ForeignKey(Group, blank=True, null=True)
objects = MyInquiryManager()
这很好,直到我做这样的事情:
inquiries = Inquiry.objects.filter(status=some_status)
my_inquiry_count = inquiries.for_user(request.user).count()
这会立即破坏一切,因为QuerySet 没有与Manager 相同的方法。我尝试创建一个自定义 QuerySet 类,并在 MyInquiryManager 中实现它,但我最终复制了我所有的方法定义。
我还发现 this snippet 有效,但我需要将额外的参数传递给 for_user 所以它会崩溃,因为它严重依赖于重新定义 get_query_set。
有没有办法在不重新定义QuerySet 和Manager 子类中的所有方法的情况下做到这一点?
【问题讨论】:
-
警告:当使用 .defer 或 .only 方法时,T.Stone 选择的答案会导致严重的性能损失(从毫秒响应时间到多秒响应)。例如,在 Django 1.3 中,如下查询: MyModel.objects.only('some_field').get(id=1) => 在 3.7 毫秒内返回,但是,如上所述添加 CustomManager,我得到: MyModel.objects .only('some_field').get(id=1) => 在 ~ 357 毫秒内返回
-
有其他人复制过这个吗? Django 1.4 怎么样?
-
好的。但是为什么以及如何发生这种情况?查询是否不同,或者您是否在没有实际访问数据库的情况下分析了该操作?
标签: django django-models django-queryset django-managers