【问题标题】:From the View, how do I pass custom "choices" into a form's ChoiceField?从视图中,如何将自定义“选择”传递到表单的 ChoiceField?
【发布时间】:2018-05-01 23:17:57
【问题描述】:

根据 Django 文档,ChoiceField 接受 an iterable of two tuples, "or a callable that returns such an iterable" 用作字段的选择。

我在表单中定义了ChoiceFields

class PairRequestForm(forms.Form):
    favorite_choices = forms.ChoiceField(choices=[], widget=RadioSelect, required=False)

这是我试图传递自定义选择元组的视图:

class PairRequestView(FormView):
    form_class = PairRequestForm

    def get_initial(self):
        requester_obj = Profile.objects.get(user__username=self.request.user)
        accepter_obj = Profile.objects.get(user__username=self.kwargs.get("username"))

        # `get_favorites()` is the object's method which returns a tuple.
        favorites_set = requester_obj.get_favorites()

        initial = super(PairRequestView, self).get_initial()

        initial['favorite_choices'] = favorites_set

        return initial

在我的models.py 中,这是上面使用的返回元组的方法:

def get_favorites(self):
        return (('a', self.fave1), ('b', self.fave2), ('c', self.fave3))

据我了解,如果我想预先填充表单,我会通过覆盖get_initial() 来传递数据。我尝试使用可调用设置表单favorite_choices 的初始数据。可调用的是favorites_set

使用当前代码,我得到一个错误'tuple' object is not callable

如何使用自己的选择预先填充 RadioSelect ChoiceField?

编辑:我也试过设置initial['favorite_choices'].choices = favorites_set

【问题讨论】:

    标签: django django-models django-forms django-templates django-views


    【解决方案1】:

    get_initial 方法用于填充表单字段的初始值。不要设置可用的choices 或修改你的字段属性。

    要成功地将您的选择从视图传递到表单,您需要在视图中实现get_form_kwargs 方法:

    class PairRequestView(FormView):
        form_class = PairRequestForm
    
        def get_form_kwargs(self):
            """Passing the `choices` from your view to the form __init__ method"""
    
            kwargs = super().get_form_kwargs()
    
            # Here you can pass additional kwargs arguments to the form.
            kwargs['favorite_choices'] = [('choice_value', 'choice_label')]
    
            return kwargs
    

    在您的表单中,从 __init__ 方法中的 kwargs 参数中获取选项并在字段中设置选项:

    class PairRequestForm(forms.Form):
    
        favorite_choices = forms.ChoiceField(choices=[], widget=RadioSelect, required=False)
    
        def __init__(self, *args, **kwargs):
            """Populating the choices of  the favorite_choices field using the favorites_choices kwargs"""
    
            favorites_choices = kwargs.pop('favorite_choices')
    
            super().__init__(*args, **kwargs)
    
            self.fields['favorite_choices'].choices = favorites_choices
    

    瞧!

    【讨论】:

    【解决方案2】:

    另一种简单的方法是:

    class PairRequestView(FormView):
        form_class = PairRequestForm
    
        def get_form(self, *args, **kwargs):
             requester_obj = Profile.objects.get(user__username=self.request.user)
             favorites_set = requester_obj.get_favorites()
             form = super().get_form(*args, **kwargs)
             form.fields['favorite_choices'].choices = favorites_set
             return form
    

    【讨论】:

      【解决方案3】:

      您应该将选择封装在表单构造函数的适当参数中。假设您有一个“组”下拉菜单,并且您想传递“组选择”:

      class CreateAccountForm(forms.Form):
      
         def __init__(self, groupChoices_, *args, **kwargs):
            super(CreateAccountForm, self).__init__(*args, **kwargs)
            self.fields['group'].choices = groupChoices_
      
         group = forms.ChoiceField()
      

      在您看来,始终使用 groupChoices_ 作为第一个参数,例如:

      groupChoices = [
        (2, 'A'),
        (4, 'B'),
      ]
      form = CreateAccountForm(groupChoices, request_.POST)
      

      不用担心kwargs太可怕了!

      【讨论】:

      • 这不能回答问题,因为 OP 使用 FormView
      猜你喜欢
      • 2020-03-29
      • 2010-12-09
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 2016-02-09
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多