Django:覆盖自定义表单的__init__

Eld*_*ila 21 python django

我在Django中创建一个自定义表单对象,它具有覆盖的__init__方法.覆盖该方法的目的是基于新参数动态生成下拉框.

例如,

class TicketForm(forms.Form):
    Type = Type.GetTicketTypeField()

    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                  initial=None, label_suffix=':', empty_permitted=False, 
                  ticket=None):

        if ticket:
           self.__class__.State = State.GetTicketStateField(ticket.Type)
           super(forms.BaseForm, self ).__init__(data=data, files=files, 
                  auto_id=auto_id, prefix=prefix, initial=initial, 
                  label_suffix=label_suffix, empty_permitted=empty_permitted)
Run Code Online (Sandbox Code Playgroud)

此解决方案不起作用.看来这些字段是在调用__init__之前创建的.我认为这个问题很常见.什么是Django处理这些类问题的方法.

Aym*_*ieh 39

您可以使用self.fieldsdict 动态修改表单.这样的事可能适合你:

class TicketForm(forms.Form):

  Type = Type.GetTicketTypeField()

  def __init__(self, ticket, *args, **kwargs):
    super(TicketForm, self).__init__(*args, **kwargs)
    self.fields['state'] = State.GetTicketStateField(ticket.Type)
Run Code Online (Sandbox Code Playgroud)


Eld*_*ila 6

我在这里找到了解决方案。如果有更好的解决方案,请回复。

class TicketForm(forms.Form):
    Type = Type.GetTicketTypeField()

    def __init__(self, ticket=None, *args, **kwargs):   
        super(TicketForm, self ).__init__(*args, **kwargs)
        if ticket:
            self.fields['State'] = State.GetTicketStateField(ticket.Type)
Run Code Online (Sandbox Code Playgroud)


Ado*_*zis 5

不要修改__init__()参数。您可能会破坏与 Django 未来版本的兼容性,并使您的代码更难以维护。

我建议使用kwargs来传递变量。

class TicketForm(forms.Form):
    type = Type.GetTicketTypeField()

    def __init__(self, *args, **kwargs):
        ticket = kwargs.pop('ticket')
        super().__init__(*args, **kwargs)
        if ticket:
            self.fields['state'] = State.GetTicketStateField(ticket.Type)
Run Code Online (Sandbox Code Playgroud)