Django переопределение filter() без изменения существующей логики кода
У меня есть таблица в production, которая интегрирована везде в системе, теперь мне нужно добавить новый столбец в таблицу со значением по умолчанию, но я не хочу менять всю существующую логику, что лучше всего для этого сделать?
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.Manager):
def get_queryset(self):
return super().get_queryset().filter(graduated=False)
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 = PeopleManager()
all = models.Manager()
Вы можете использовать People.all.all()
для получения всех People
, и People.objects.all()
для получения всех People
, которые не закончили школу.
С другой стороны, я не рекомендую этого делать: часто People.objects.all()
создает впечатление, что человек получит все People
. Как говорится в Zen of Python: "explicit over implicit": лучше, чтобы код объяснял и подсказывал, что он делает, а не перемещал фильтрацию куда-то в менеджер.