Django 在不改变现有代码逻辑的情况下覆盖 filter()
Django overriding filter() without change existing code logic
我在生产中有一个 table 集成在系统的任何地方,现在我需要在 table 中添加一个具有默认值的新列,但不想更改所有现有的逻辑,最好的方法是什么?
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
在系统中,我们到处都有这样的查询
People.objects.filter(gender='male')
People.objects.filter(gender='female', class="3rd")
...
现在我们需要添加一个新字段:
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
graduated = models.BooleanField(default=False)
假设所有现有数据都应该有 graduated
是 False,所以如果我们可以在每个查询上添加 graduated=False
,那么所有现有逻辑都应该有效,但是我们有什么办法可以做到这一点我们不需要更改任何现有代码,但他们会假设 graduated=False
?
是的,您可以创建一个管理器,使 .objects
仅保留 People
和 graduated=False
:
class PeopleManager(models.<strong>Manager</strong>):
def get_queryset(self):
return super().get_queryset()<strong>.filter(graduated=False)</strong>
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
graduated = models.BooleanField(default=False)
objects = <strong>PeopleManager()</strong>
all = models.Manager()
您可以使用 People.all.all()
检索所有 People
,并使用 People.objects.all()
检索所有未毕业的 People
。
话虽这么说,但我不推荐这样做:通常 People.objects.all()
给人的印象是人们会检索 所有 People
。正如 Python 的 Zen 所说:“显式优于隐式 ”:代码最好解释并暗示它在做什么,而不是将过滤移动到隐藏在管理器中的某处。
我在生产中有一个 table 集成在系统的任何地方,现在我需要在 table 中添加一个具有默认值的新列,但不想更改所有现有的逻辑,最好的方法是什么?
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
在系统中,我们到处都有这样的查询
People.objects.filter(gender='male')
People.objects.filter(gender='female', class="3rd")
...
现在我们需要添加一个新字段:
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
graduated = models.BooleanField(default=False)
假设所有现有数据都应该有 graduated
是 False,所以如果我们可以在每个查询上添加 graduated=False
,那么所有现有逻辑都应该有效,但是我们有什么办法可以做到这一点我们不需要更改任何现有代码,但他们会假设 graduated=False
?
是的,您可以创建一个管理器,使 .objects
仅保留 People
和 graduated=False
:
class PeopleManager(models.<strong>Manager</strong>):
def get_queryset(self):
return super().get_queryset()<strong>.filter(graduated=False)</strong>
class People(models.Model):
name = models.CharField(max_length=20)
gender = models.CharField(max_length=20)
class = models.CharField(max_length=20)
graduated = models.BooleanField(default=False)
objects = <strong>PeopleManager()</strong>
all = models.Manager()
您可以使用 People.all.all()
检索所有 People
,并使用 People.objects.all()
检索所有未毕业的 People
。
话虽这么说,但我不推荐这样做:通常 People.objects.all()
给人的印象是人们会检索 所有 People
。正如 Python 的 Zen 所说:“显式优于隐式 ”:代码最好解释并暗示它在做什么,而不是将过滤移动到隐藏在管理器中的某处。