我的数据库中有用户表,它们可以是活动的或不活动的。如果我只想查询活动用户,则可以定义一个代理模型,如下所示。
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的模型,代码看起来很凌乱。我可以知道我们是否可以有更优雅的方式吗?
谢谢 亚历克斯
答案 0 :(得分:2)
我真的会避免覆盖.objects
管理器,并将其用作某种隐式过滤。 Python的 Zen 优于 explicit优于隐式,通过使用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
,因此您无法对此进行额外的修补。
现在,我们可以以一种非常优雅的方式定义一些经理:
@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()
进行查询(好吧,我们可以像执行.objects
一样执行所有操作,但是可以执行.active_users
。
答案 1 :(得分:0)
我创建了一个只有用户模型的新Django项目。我的models.py看起来像这样
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
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
@filter_manager(active=True)
class ActiveManager(models.Manager):
pass
@filter_manager(active=False)
class InactiveManager(models.Manager):
pass
class User(models.Model):
name = models.CharField(max_length=50)
location = models.CharField(max_length=50)
active = models.BooleanField()
active_user = ActiveManager()
当我尝试User.objects.all()时。
错误:type object 'User' has no attribute 'objects'