我有模型,其中对象与日期有关,但它们之间的关系依赖于日期。所以,仅仅是为了说明,我可能有
class ValidCommonManager(models.Manager):
ValidCommonManager(self, date):
self.date = date
def get_query_set(self):
return super(ValidCommonManager, self).get_query_set().filter(
models.Q(start__isnull=True)|
models.Q(start__lte=self.date)
).filter(
models.Q(end__isnull=True)|
models.Q(end__gte=self.date)
)
class CommonModel(models.Model):
start = models.DateTimeField(null=True)
end = models.DateTimeField(null=True)
valid_objects = ValidCommonManager(now())
objects = models.Manager()
class Group(CommonModel):
name = models.CharField(max_length=25)
description = models.TextField(blank=True)
group_members = models.ManyToManyField(
'Person', through='GroupMember')
class GroupMember(CommonModel):
group = models.ForeignKey(Group)
member = models.ForeignKey(Person)
class Person(CommonModel):
name = models.CharField(max_length=100)
现在该组可能从日期A到日期Z存在,但成员资格在日期B和日期C可能不同,这由GroupMember中的开始和结束字段反映。现在,在我正在使用
处理时,很容易找到活动的组groups = Group.valid_objects.all()
但我无法找到一个简单的方法来让小组成员在给定日期之前
members_of_my_group = group.group_members.filter(
models.Q(start__isnull=True)|
models.Q(start__lte=date)
).filter(
models.Q(end__isnull=True)|
models.Q(end__gte=date)
).filter(
models.Q(group_member__start__isnull=True)|
models.Q(group_member__start__lte=date)
).filter(
models.Q(group_member__end__isnull=True)|
models.Q(group_member__end__gte=date)
)
迅速变得笨拙并且违反了DRY的基础知识。我在use_for_related_fields
上设置了ValidCommonManager
,但Django docs承诺在过滤的管理员身上做出令人讨厌的事情。
答案 0 :(得分:1)
相关管理员只是为了方便起见,您始终可以为Manager
定义一个可以执行相同操作的自定义Person
。 (另请注意,从Django 1.7开始,您可以根据具体情况指定要用于相关查找的管理器。有关详细信息,请参阅the docs。)
即,
group_members = Group.group_members.filter(...)
相当于:
class PersonManager(models.Manager):
def get_valid_members(self, group):
return self.filter(groupmember__group=group,
Q(groupmember__start__isnull=True)...
group_members = Person.objects.get_valid_members(group)
另一种方法是使用子查询:
group_members = Person.objects.filter(groupmember__in=
GroupMember.valid_objects.filter(group=group))