【发布时间】:2011-07-18 02:34:21
【问题描述】:
根据登录的用户(一种特定于对象的权限),我已覆盖模型的默认管理器,以便仅显示允许的项目:
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 时,都会检索当前用户并对默认查询集应用过滤器,以便仅显示允许的记录。
然后,我有一个带有 Foo 的 ForeignKey 的模型:
class Bar(models.Model):
foo = models.ForeignKey(Foo)
class BarForm(form.ModelForm):
class Meta:
model = Bar
当我编写 BarForm 时,我希望只看到过滤器 Foo 实例,但未应用过滤器。我认为这是因为查询集是在 Django 启动时评估和缓存的,当时没有用户登录,也没有应用过滤器。
有没有一种方法可以让 Django 在运行时评估 ModelChoice 查询集,而不必在表单定义中明确说明? (尽管存在所有性能问题...)
编辑 我找到了查询集的评估位置(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)
有什么提示吗?
【问题讨论】:
-
ModelChoice 的查询集已经很懒惰了,可能您正在某处评估查询集,显示一些代码(管理器 + 表单实现)会有所帮助:)
-
我已经添加了代码。在自定义管理器中放置一个断点,我看到 get_queryest' 仅在 Django 启动时评估(当消息 'Validating models...` 显示在 'runserver' 中时)
标签: django memcached foreign-key-relationship django-queryset