【问题标题】:django forms - overriding constructor for changing field type depending by inputdjango forms - 用于根据输入更改字段类型的重写构造函数
【发布时间】:2012-05-19 23:39:32
【问题描述】:

我需要重写表单的构造函数:如果我在输入中有一些值,则某些字段必须是 ChoiceField,否则它们必须是 CharField。这是代码:

class AnagraficaForm(forms.Form):

    usertype = ((1,'Privato'),(0,'Libero professionista/Azienda'))
    nome = forms.CharField(max_length=100)
    cognome = forms.CharField(max_length=100)
    telefono = forms.CharField(max_length=50,required=False)
    email= forms.EmailField(max_length=100,required=False)
    indirizzo = forms.CharField(max_length=100)
    nazione = forms.ChoiceField(choices = util.get_countries_tuple_list())
    provincia = forms.CharField(max_length=100)
    citta = forms.CharField(max_length=100)
    cap = forms.CharField(max_length=10)
    codfisc = ITSocialSecurityNumberField(required=False)
    piva = ITVatNumberField(required=False)
    ragsociale = forms.CharField(max_length=100,required=False)
    is_privato = forms.TypedChoiceField(
        initial=1,
        coerce=lambda x: bool(int(x)),
        choices=usertype,
        #using custom renderer to display radio buttons on the same line
        widget=forms.RadioSelect(renderer=HorizRadioRenderer, attrs={"id":"is_privato"})
    )

    def __init__(self, country_name = 'ITALIA', region_name = 'MILANO', city_name = 'MILANO', zipcode = '', *args, **kwargs):
        if country_name != 'ITALIA':
            print 'in if'
            self.nazione = forms.ChoiceField(choices = util.get_countries_tuple_list())
            self.provincia = forms.CharField(max_length=100, initial = region_name)
            self.citta = forms.CharField(max_length=100, initial = city_name)
            self.cap = forms.CharField(max_length=10, initial = zipcode)
            kw = {'initial':{'nazione': util.get_country_id(country_name)}}
            kw.update(kwargs)
            return super(AnagraficaForm, self).__init__(*args, **kw)
        else:
            print 'in else'
            self.nazione = forms.ChoiceField(choices = util.get_countries_tuple_list())
            self.provincia = forms.ChoiceField(choices = util.get_regions_tuple_list(util.get_country_id(country_name)))
            self.citta = forms.ChoiceField(choices = util.get_cities_tuple_list(util.get_country_id(country_name), util.get_region_code(region_name)))
            self.cap = forms.ChoiceField(choices = util.get_zips_tuple_list(util.get_country_id(country_name), util.get_region_code(region_name), city_name))
            initial = {
                        'nazione' : 'IT',
                        'provincia' : util.get_region_code(region_name),
                        'citta' : util.get_region_from_cityname(city_name),
                        'cap' : util.get_city_id(zipcode)
                      }
            kw = {'initial': initial}
            kw.update(kwargs)
            return super(AnagraficaForm, self).__init__(*args, **kw)

但是这种方式行不通。即使我将之前的字段声明为 CharField,然后在 init 中覆盖它们,它们也不会在模板中呈现(我收到此消息:)。

有什么帮助吗?

谢谢

【问题讨论】:

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


    【解决方案1】:

    您应该在创建表单之后操作self.fields[name],而不是在它之前触摸self.field。例如,而不是:

    self.nazione = forms.ChoiceField(choices = util.get_countries_tuple_list())
    super(AnagraficaForm, self).__init__(*args, **kw)
    

    应该有(顺便说一句,__init__ 应该什么都不返回):

    super(AnagraficaForm, self).__init__(*args, **kw)
    self.fields['nazione'] = forms.ChoiceField(choices = util.get_countries_tuple_list())
    

    或者,如果两个字段的类型相同,只需修改必要的属性:

    self.fields['nazione'].choices = util.get_countries_tuple_list()
    

    【讨论】:

    • 谢谢,它成功了 :) 无论如何,现在我遇到了验证该表单的问题,这是视图:dpaste.com/750548 --> 表单始终无效,form.errors 也打印显示一个空的字典。表单被返回,而不是将 ChoiceFields 呈现为选择,我在 html 中打印了这些消息:...其他有用的帮助?谢谢!
    • 已解决(我没有将正确的输入传递给表单实例构造函数)。还是谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多