gpt4 book ai didi

Django:使 ModelChoiceField 在运行时评估查询集

转载 作者:行者123 更新时间:2023-12-02 01:20:30 25 4
gpt4 key购买 nike

我已经覆盖了模型的默认管理器,以便根据登录的用户(一种特定于对象的权限)仅显示允许的项目:

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 的外键的模型:

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\lated.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)

有什么提示吗?

最佳答案

正是遇到这个问题 - 需要使用组中的用户对象填充选择表单,但 fun_vit 的答案不正确(至少对于 django 1.5)

首先,您不想覆盖 field['somefield'].choices 对象 - 它是一个 ModelChoiceIterator 对象,而不是查询集。其次,django.forms.BaseForm 中的注释警告您不要覆盖 base_fields:

    # The base_fields class attribute is the *class-wide* definition of
# fields. Because a particular *instance* of the class might want to
# alter self.fields, we create self.fields here by copying base_fields.
# Instances should always modify self.fields; they should not modify
# self.base_fields.

这对我有用(django 1.5):

class MyForm(ModelForm):
users = ModelMultipleChoiceField(queryset=User.objects.none())

def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args,**kwargs)

site = Site.objects.get_current()
self.fields['users'].queryset = site.user_group.user_set.all()

class Meta:
model = MyModel

关于Django:使 ModelChoiceField 在运行时评估查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5351383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com