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": лучше, чтобы код объяснял и подсказывал, что он делает, а не перемещал фильтрацию куда-то в менеджер.

Вернуться на верх