Django:为自定义表单重写__init__

28 投票
3 回答
51931 浏览
提问于 2025-04-15 11:37

我正在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)

这个解决方案不起作用。看起来这些字段是在__init__方法被调用之前就已经创建了。我想这个问题应该很常见。那么在Django中,处理这类问题的正确方法是什么呢?

3 个回答

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)
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)
53

你可以通过使用 self.fields 这个字典来动态修改你的表单。你可以试试下面这样的做法:

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)

撰写回答