我有以下设置:
from django.db import models
class BaseInfoQuerySet(models.query.QuerySet):
def public(self):
return self.filter(public=True)
def not_grouped(self):
return self.filter(bu_group=True)
class BUManager(models.Manager):
def get_queryset(self):
return BaseInfoQuerySet(self.model, using=self._db).extra(
select={'null_group': 'bu_group_id IS NULL'},
order_by=['null_group'])
class BU(models.Model):
# some field definitions
# option 1 (preferred)
objects = BaseInfoQuerySet.as_manager()
# option 2
objects = BUManager()
Run Code Online (Sandbox Code Playgroud)
我正在使用Django 1.8和Python 2.7。
我要实现的是能够使用,# option 1但其中的所有方法BaseInfoQuerySet都应使用get_queryset()from的修饰符BUManager。BaseInfoQuerySet用作其他模型的多个查询集的基类,因此我不想摆脱它而仅使用models.Manager。而且我还希望能够链接QuerySet过滤器(例如BU.objects.public().not_grouped())。
我认为解决方案的方式是修改某种方法as_manager()以返回Manager使用重写get_queryset方法的修改。
我使用 Python3 和 Django1.10 对此进行了测试,因为这是我现在可用的环境。让我知道是否需要更改任何内容才能使其在您的环境中运行。
您可以get_queryset在运行时在管理器实例上设置一个新方法,如下所示:
import types
from django.db import models
class BaseInfoQuerySet(models.query.QuerySet):
def public(self):
return self.filter(public=True)
def not_grouped(self):
return self.filter(bu_group=True)
@classmethod
def as_manager(cls):
def get_queryset(self):
return BaseInfoQuerySet(self.model, using=self._db).extra(
select={'null_group': 'bu_group_id IS NULL'},
order_by=['null_group'])
manager = super(BaseInfoQuerySet, cls).as_manager()
manager.get_queryset = types.MethodType(get_queryset, manager)
return manager
Run Code Online (Sandbox Code Playgroud)
但这对我来说看起来不必要的复杂。我最终选择了你的选项#2。
如果您确实选择选项#2,请记住将 QuerySet 的方法克隆到 Manager 上或使用通用 mixin。
| 归档时间: |
|
| 查看次数: |
834 次 |
| 最近记录: |