如何向Django的ModelForm实例传递初始参数?

22 投票
3 回答
36578 浏览
提问于 2025-04-15 15:47

我遇到的情况是这样的:

我有一个交易模型,里面有几个字段:fromto(这两个字段都是指向auth.User模型的外键)和amount。在我的表单中,我想让用户填写两个字段:amountfromto字段会在视图函数中自动设置为当前用户)。

默认情况下,ForeignKey字段会用一个下拉框来显示。但是我想要的是,只让用户选择他们的同伴(user.peers)作为选项,这样用户只能和他们的同伴进行交易,而不会被系统中的所有用户搞得眼花缭乱。

我尝试把模型表单改成这样:

class AddTransaction(forms.ModelForm):
  from = ModelChoiceField(user.peers)
  amount = forms.CharField(label = 'How much?')

  class Meta:
    model = models.Transaction

但是看起来我必须在这里传递ModelChoiceField的选项查询集,而在这个地方我无法访问到网络请求中的request.user对象。

我该如何将表单中的选项限制为用户相关的呢?

3 个回答

2

把用户信息传递给表单的 __init__ 方法,然后调用 super(…)。接着,把 self.fields['from'].queryset 设置为 user.peers

8

我也遇到过这个问题,下面是我的解决办法:

class ChangeEmailForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(ChangeEmailForm, self).__init__(*args, **kwargs)
        self.fields['email'].initial = user.email

    class Meta:
        model = User
        fields = ('email',)

    def save(self, commit=True):
        self.user.email = self.cleaned_data['email']
        if commit:
            self.user.save()
        return self.user
37

使用下面的方法(希望这个方法足够清晰):

class BackupForm(ModelForm):
    """Form for adding and editing backups."""

    def __init__(self, *args, **kwargs):
        systemid = kwargs.pop('systemid')
        super(BackupForm, self).__init__(*args, **kwargs)
        self.fields['units'] = forms.ModelMultipleChoiceField(
                required=False,
                queryset=Unit.objects.filter(system__id=systemid),
                widget=forms.SelectMultiple(attrs={'title': _("Add unit")}))

    class Meta:
        model = Backup
        exclude = ('system',)

创建像这样的表单:

form_backup = BackupForm(request.POST,
                         instance=Backup,
                         systemid=system.id)
form_backup = BackupForm(initial=form_backup_defaults,
                         systemid=system.id)

希望这能帮到你!如果你需要我更详细地解释,请告诉我。

撰写回答