django - Django - 将代理模型简化为单个类
问题描述
我的数据库中有用户表,它们可以是活动的或非活动的。如果我只想查询活动用户,我会定义一个如下所示的代理模型。
class User(models.Model):
name = models.CharField(max_length=50)
location = models.CharField(max_length=50)
active = models.BooleanField()
class UserActive(models.Manager):
def get_queryset(self):
return super(UserActive, self).get_queryset().filter(active=True)
class ActiveUser(User):
objects = UserActive()
class Meta:
proxy = True
然后通过使用 ActiveUser,我可以只对活动用户进行计算/统计。
问题是,我需要同时定义 UserActive 和 ActiveUser 类,这对我来说似乎很尴尬。因为对于每个主类(在本例中是 User),我们需要定义另外两个类。想象一下我们还有其他几个模型需要实现 Proxy,代码看起来会很乱。我可以知道我们是否可以有更优雅的方式?
谢谢亚历克斯
解决方案
我真的会避免覆盖.objects
管理器,并将其用作某种隐式过滤。Python之禅是显式优于隐式,通过使用ActiveUser
,你基本上实现了一个过滤管理器,但是像整个集合一样提出它。
也许更优雅的解决方案是定义多个管理器。所以我们可以构造一个过滤管理器装饰器:
def filter_manager(**kwargs):
def decorator(klass):
def get_queryset(self):
return super(klass, self).get_queryset().filter(**kwargs)
klass.get_queryset = get_queryset
return klass
return decorator
然而,这个装饰器会丢弃get_queryset
在管理器本身上定义的 a,所以你不能用它执行额外的补丁。
现在我们可以用一种相当优雅的方式定义一些管理器:
@filter_manager(active=True)
class ActiveManager(models.Manager):
pass
@filter_manager(active=False)
class InactiveManager(models.Manager):
pass
最后,我们可以将这些管理器添加到User
模型中,并使用明确的名称:
class User(models.Model):
name = models.CharField(max_length=50)
location = models.CharField(max_length=50)
active = models.BooleanField()
objects = models.Manager()
active_users = ActiveManager()
inactive_users = InactiveManager()
所以现在我们可以User.active_users
用来查询活跃用户。因此,我们没有代理模型,并且可以使用User.active_users.count()
例如查询(我们可以执行所有操作,例如 with.objects
但然后 for .active_users
。
推荐阅读
- node.js - 带有 ReactJS + React-Router-Dom 的 NodeJS 工作不正确
- php - 如何在php中显示评论通知
- java - 观看奖励视频后,如何在 1 天内停止在 android 应用中显示所有广告?
- java - 从字节数组中识别 ProtoBuf 类
- express - 有什么方法可以在我用 ExpressJS 制作的 web 应用程序中使用 google 域身份验证
- python - 分组箱线图
- php - PHP - Laravel - 管理条件规则的最佳方式
- python - 在金字塔应用程序中何时/何处验证 openid 令牌?
- android - 既然 Gradle 和 Maven 都弃用了 http,如何使用 Liferay Mobile SDK 6.2.18 生成 jar 库?
- omnet++ - Omnet ini 配置文件 - 为每个节点设置随机目的地