Я переопределил диспетчер моих моделей по умолчанию, чтобы отображать только разрешенные элементы в соответствии с зарегистрированным пользователем (своего рода объектное разрешение):
class User_manager(models.Manager):
def get_query_set(self):
""" Filter results according to logged user """
#Compose a filter dictionary with current user (stored in a middleware method)
user_filter = middleware.get_user_filter()
return super(User_manager, self).get_query_set().filter(**user_filter)
class Foo(models.Model):
objects = User_manager()
...
Таким образом, всякий раз, когда я использую Foo.objects
, текущий пользователь извлекается, и фильтр применяется к набору запросов по умолчанию, чтобы отображать только разрешенные записи.
Затем у меня есть модель с ForeignKey для Foo:
class Bar(models.Model):
foo = models.ForeignKey(Foo)
class BarForm(form.ModelForm):
class Meta:
model = Bar
Когда я составляю BarForm, я ожидаю увидеть только экземпляры filteres Foo, но фильтр не применяется. Я думаю, это потому, что набор запросов оценивается и кэшируется при запуске Django, когда ни один пользователь не зарегистрирован и фильтр не применяется.
Есть ли способ заставить Django оценивать набор запросов ModelChoice во время выполнения, не делая его явным в определении формы? (несмотря на все проблемы с производительностью...)
EDIT Я нашел, где оценивается набор запросов (django\db\models\fields\related.py: 887):
def formfield(self, **kwargs):
db = kwargs.pop('using', None)
defaults = {
'form_class': forms.ModelChoiceField,
'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to),
'to_field_name': self.rel.field_name,
}
defaults.update(kwargs)
return super(ForeignKey, self).formfield(**defaults)
Любой намек?