У меня есть логический флаг private
на моей модели и пользовательский менеджер, который перезаписывает метод get_query_set с фильтром, удаляя private = True:
class myManager(models.Manager):
def get_query_set(self):
qs = super(myManager, self).get_query_set()
qs = qs.filter(private=False)
return qs
class myModel(models.Model):
private = models.BooleanField(default=False)
owner = models.ForeignKey('Profile', related_name="owned")
#...etc...
objects = myManager()
Я хочу исключить набор запросов по умолчаниючастные модели по умолчанию используются в качестве меры безопасности, предотвращая случайное использование модели, показывающей частные модели.
Иногда, однако, я хочу показать частные модели, поэтому в диспетчере у меня есть следующее:
def for_user(self, user):
if user and not user.is_authenticated():
return self.get_query_set()
qs = super(myManager, self).get_query_set()
qs = qs.filter(Q(owner=user, private=True) | Q(private=False))
return qs
Это отлично работает, за исключением того, что я не могу зацепить фильтр.Это становится проблемой, когда у меня есть fk, указывающий на myModel, и использую otherModel.mymodel_set.otherModel.mymodel_set.for_user (user) не будет работать, потому что mymodel_set возвращает объект QuerySet, а не менеджера.
Теперь начинается настоящая проблема, так как я не вижу способа заставить метод for_user () работатьв подклассе QuerySet, потому что я не могу получить доступ к полному нефильтрованному набору запросов (в основном перезаписывая get_query_set) из подкласса QuerySet, как я могу в менеджере (используя super () для получения базового набора запросов.)
Каков наилучший способ обойти это?
Я не привязан к какому-либо конкретному интерфейсу, но мне бы хотелось, чтобы он был как можно более djangoy / DRY.Очевидно, я мог бы сбросить защиту и просто вызвать метод для фильтрации частных задач при каждом вызове, но я действительно не хочу этого делать.
Обновление
Ответ Манджи ниже очень близок, однако он терпит неудачу, когда требуемый набор запросов не является подмножеством набора запросов по умолчанию.Я предполагаю, что реальный вопрос здесь состоит в том, как я могу удалить определенный фильтр из цепочечного запроса?