Написание менеджера для фильтрации результатов набора запросов - PullRequest
6 голосов
/ 23 декабря 2009

У меня есть следующий код:

class GroupDepartmentManager(models.Manager):
  def get_query_set(self):
    return super(GroupDepartmentManager, self).get_query_set().filter(group='1')

class Department(models.Model):
 name = models.CharField(max_length=128)
 group = models.ForeignKey(Group)
 def __str__(self):
    return self.name
 objects = GroupDepartmentManager()

... и работает нормально. Единственное, что мне нужно заменить group='1' на group=(the group specified by group = models.ForeignKey(Group)). Я довольно долго пытался определить, нужно ли передавать этот внешний ключ в класс, или в функцию get_query_set, или что. Я знаю, что вы можете сделать это с помощью group.department_set.filter(group=desired group), но я пишу эту модель для сайта администратора, поэтому мне нужно использовать переменную, а не константу после знака =.

Ответы [ 2 ]

4 голосов
/ 24 декабря 2009

У меня есть догадка, что замена по умолчанию Manager на objects таким способом может быть не очень хорошей идеей, особенно если вы планируете использовать сайт администратора ... Даже если это поможет вам с вашими сотрудниками, это совсем не поможет вам при работе с отделами. Как насчет второго свойства, предоставляющего ограниченный вид на Департаменты наряду с обычным objects? Или переместите стандартный Manager с objects на _objects и переименуйте from_same_group в objects, если вы действительно предпочитаете оригинальный подход для своего приложения.

class Department(models.Model):
    name = models.CharField(max_length=128)
    group = models.ForeignKey(Group)
    def __str__(self):
        return self.name
    objects = models.Manager()

    @property
    def from_same_group(self):
        return Department.objects.filter(group__exact=self.group)

Кроме того, я понимаю, вы знаете, как настроить админ-сайт, чтобы воспользоваться забавным Manager; если нет (или если я как-то неправильно понял ваш вопрос), оставьте комментарий, я постараюсь ответить в ближайшее время.


РЕДАКТИРОВАТЬ: ОК, чтобы прояснить это: если вы действительно настаиваете на замене objects, вы, вероятно, захотите сделать это:

class Department(models.Model):
    name = models.CharField(max_length=128)
    group = models.ForeignKey(Group)
    def __str__(self):
        return self.name

    _objects = models.Manager()

    @property
    def objects(self):
        # note the _objects in the next line
        return Department._objects.filter(group__exact=self.group)
2 голосов
/ 24 декабря 2009

Возможно, вы захотите пересмотреть отношения между группами и отделами, если обнаружите, что попытка создать собственного менеджера слишком сложна. Менеджеры преуспевают в упрощении общих запросов, но проваливаются в отображении сложных отношений между моделями и экземплярами моделей.

Однако я думаю, что эта статья о фильтрации объектов модели с помощью собственного менеджера укажет вам правильное направление. Автор предлагает метод выполнения вызова функции, который возвращает настроенный класс диспетчера, в котором заданные вами параметры фильтра сохранены в классе, чтобы они не передавались в экземпляр. Сделай это!

...