2009-12-23 3 views
6

У меня есть следующий код:Написание менеджера для фильтрации набора результатов запроса

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

У меня есть некоторые проблемы с пониманием того, чего вы пытаетесь достичь. Вы хотите, чтобы department_instance.objects.all() возвращал только те отделы, которые находятся в той же группе, что и department_instance? - Maciej Pasternacki 0 секунд назад –

+0

Да, Джон ваш случай не ясен. Какая определенная группа должна быть выбрана, например, Department.objects.all()? – kibitzer

+0

Хорошо, так что есть список групп. В каждой группе есть несколько департаментов. У меня также есть Сотрудники. Каждый сотрудник принадлежит к одной группе и одному отделу. Когда я редактирую сотрудника, раскрывающийся список отделений показывает все отделы в базе данных, а не только отделы в группе сотрудников. Итак, я хочу показывать только департаменты в группе сотрудников. Я думал, что могу сделать это, ограничив результаты department_set, чтобы быть отделами в определенной группе. Возможно, я действительно смущен. Но этого я и пытаюсь достичь. – John

ответ

4

У меня есть догадка, что замена по умолчанию Manager на objects таким образом может быть неправильной идеей, особенно если вы планируете использовать админ-сайт ... Даже если это поможет вам с вашими сотрудниками, t помочь вам при работе с отделами. Как насчет второго имущества, предоставляющего ограниченное представление о департаментах наряду с обычным 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; если нет (или если я неправильно понял ваш вопрос как-то), оставьте комментарий, я постараюсь последовать за ним в ближайшее время.


EDIT: OK, чтобы сделать это более ясно: если вы абсолютно настаивают на замене 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) 
+0

Боюсь, у меня нет подсказки. Я изменил from_same_publisher на from_same_group. Но не хочу ли я сказать объекты = from_same_publisher()? – John

+0

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

+0

Спасибо, но я добавил это в класс Департамента, и поле выбора все еще показывает все объекты Департамента. Я думаю, что мне еще нужно настроить страницу администрирования, как вы указали, воспользоваться этой настройкой. Я смущен, потому что я думал, что все бизнес-менеджер состоялся внутри models.py, без изменений в admin.py. – John

2

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

Однако, думаю, эта статья о filtering model objects with a custom manager укажет вам в правильном направлении. Автор предлагает метод выполнения вызова функции, который возвращает настраиваемый класс менеджера, который имеет параметры фильтра, указанные вами в классе, поэтому они не передаются экземпляру. Сделай это!

+0

Отличная ссылка, спасибо. Это определенно взломать, но я попробую это и отчитаю. – John

+0

Ни в коем случае! Это слишком динамично, чтобы быть взломом! Я на самом деле думаю, что это довольно умно. – jathanism

+0

Достаточно честно! Я реализовал это с помощью «objects = get_filter_manager (group = group)» в классе Департамента и получил тот же самый камень преткновения, который я всегда получал раньше: «Объект« str »не имеет атрибута« create_counter ». Кажется, я не могу получить код в отступе, или я бы опубликовал его все здесь. – John