Django: Overriding __init__ for Custom Forms

Question:

I am making a custom form object in Django which has an overrided __init__ method. The purpose of overriding the method is to dynamically generate drop-down boxes based on the new parameters.

For example,

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)

This solution does not work. It appears that the fields are created before the __init__ is called. I would assume this problem would be pretty common. What would be the Django way of handling these classes of problems.

Asked By: Eldila

||

Answers:

You can dynamically modify your form by using the self.fields dict. Something like this may work for you:

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)
Answered By: Ayman Hourieh

I found a solution here. If there is a better solution, please post a reply.

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)
Answered By: Eldila

Don’t modify the __init__() parameters. You may break compatibility with future versions of Django and make your code harder to maintain.

I suggest using the kwargs to pass your variables.

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)
Answered By: Adonis Gaitatzis
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.