【问题标题】:Setting initial Django form field value in the __init__ method在 __init__ 方法中设置初始 Django 表单字段值
【发布时间】:2014-04-18 21:12:09
【问题描述】:

Django 1.6

我在 Django 表单类中有一个工作代码块,如下所示。我从中构建表单字段列表的数据集可以包含任何字段的初始值,并且我在表单中设置该初始值没有成功。下面的if field_value: 块确实填充了初始表单字典属性,但没有显示初始值。请注意(如果您想知道).initial 属性直到super() 调用之后才存在。

这个可以吗?

如果是这样,我做错了什么?

谢谢!

def __init__(self, *args, **kwargs):
    id = kwargs.pop('values_id', 0)
    super(LaunchForm, self).__init__(*args, **kwargs)
    # Lotsa code here that uses the id value
    # to execute a query and build the form
    # fields and their attributes from the 
    # result set

    if field_value:
        self.initial[field_name] = field_value

【问题讨论】:

  • 我的问题是我在 设置 self.initial... 之后调用 super.__init... 嘘!

标签: python django django-1.6


【解决方案1】:

我遇到了同样的问题,然后我解决了这个问题:

def __init__(self, *args, **kwargs):
    instance = kwargs.get('instance', None)

    kwargs.update(initial={
        # 'field': 'value'
        'km_partida': '1020'
    })

    super(ViagemForm, self).__init__(*args, **kwargs)

    # all other stuff

【讨论】:

    【解决方案2】:

    试试这个方法:

    super(ViagemForm, self).__init__(*args, **kwargs)
    
    if field_value:
        #self.initial[field_name] = field_value
        self.fields[field_name].initial = field_value
    

    【讨论】:

    • @ndpu - 谢谢,但这也不起作用 - 字段对象存在,并且它具有“初始”的数据属性,确实设置为初始值,但它没有显示在表格上。 @karthikr - 建立表单字段的代码在 super() 调用之后执行,直到此代码执行,我才知道初始值应该是什么。我也尝试了 `self.initial.update({field_name: field_value})' 但这也使页面上的字段空白。我还尝试将初始字段参数设置为字段定义的一部分 - 这种方法没有成功。
    • 好吧。我使用与答案中显示的完全相同的代码,它对我有用。
    • @karthikr - 我的猜测是你的工作是因为你在设置属性之后调用 super() 。星期五玩这个变得更加有趣 - 我不仅可以验证初始值是否存在,它也是一个必填字段,并且值的存在导致表单在视图的 post() 方法中传递 is_valid() !所以,我得到了最糟糕的一切 - 价值在那里并且经过验证,但不会显示在表单上!
    • 我并没有更接近于让它按照我需要的方式工作,但我正在做出一些发现,失败可能不在于我如何填充初始值,但与字段类型的行为(或我对该行为的理解)有关。我将发布一个涉及该问题这方面的新主题。感谢您的所有意见。
    • 您必须先使用super 初始化表单才能使self.fields 可用
    【解决方案3】:

    我想提一下,尽管这可能无法解决您的问题,但发送到表单的“初始”dict kwarg 似乎优先于field['field_name'].initial

    class MyView(View):
        form = MyForm(initial={'my_field': 'first_value'})
    
    class MyForm(Form):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['my_field'].initial = 'second_value'
    

    my_field 渲染将初始设置为'first_value'

    一些选项(除其他外)可能是:

    在初始化表单之前在视图中确定second_value

    class MyView(View):
        # determine second_value here
        form = MyForm(initial={'my_field': 'second_value'})
    

    在调用super()之前将initial中的second_value替换为first_value

    class MyForm(Form):
        def __init__(self, *args, **kwargs):
            # determine second_value here
            if kwargs.get('initial', None):
                kwargs['initial']['my_field'] = 'second_value'
            super().__init__(*args, **kwargs)
    

    在调用super()之前确保'first_value'不在kwargs['initial']中:

    class MyForm(Form):
        def __init__(self, *args, **kwargs):
            if kwargs.get('initial', None):
                if kwargs['initial']['my_field']
                    del(kwargs['initial']['my_field']
            super().__init__(*args, **kwargs)
            # determine second_value here
            self.fields['my_field'].initial = 'second_value'
    

    【讨论】:

      【解决方案4】:

      我在为名为“needs_response”的单选按钮设置初始值时遇到了类似的问题,并通过检查自身的属性并引用“declared_fields”解决了这个问题:

          # views.py
          def review_feedback_or_question(request, template, *args, **kwargs):
              if 'fqid' in kwargs:
                  fqid = kwargs['fqid']
              submission = FeedbackQuestion.objects.get(pk=fqid)
              form = FeedbackQuestionResponseForm(submission_type=submission.submission_type)
              # other stuff
      
          # forms.py
          class FeedbackQuestionResponseForm(forms.Form):
              CHOICES = (('1', 'Yes'), ('2', 'No'))
              response_text = forms.CharField(
                  required=False,
                  label='',
                  widget=forms.Textarea(attrs={'placeholder': 'Enter response...'}))
              needs_response = forms.ChoiceField(choices=CHOICES,
                  label='Needs response?',
                  widget=forms.RadioSelect())
              def __init__(self, *args, **kwargs):
                  if 'submission_type' in kwargs:
                      submission_type = kwargs.pop('submission_type')
                      if submission_type == 'question':
                          self.declared_fields['needs_response'].initial = 1
                      else:
                          self.declared_fields['needs_response'].initial = 2
                  super(FeedbackQuestionResponseForm, self).__init__(*args, **kwargs)
      

      【讨论】:

        【解决方案5】:

        这行得通:

        class BarForm(forms.ModelForm):
        
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.fields['state'] = forms.ChoiceField(
                    required=False,
                    choices=Foo.ADDRESS_STATE_CHOICES,
                    disabled='disabled',
                    initial='xyz',
                )
        
            state = forms.ChoiceField(
                label='State',
                choices=Foo.ADDRESS_STATE_CHOICES,
                initial='foo',
            )
        

        【讨论】:

          【解决方案6】:

          在字段定义中设置initial= "" 将解决您的问题。两种建议的方法都是正确的,您只需在字段定义中定义initial= "",问题就解决了

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-23
            • 2019-03-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-17
            • 1970-01-01
            相关资源
            最近更新 更多