[Fixed]-Clarify Django Choices Mechanics


This is more of a Python question than a Django question, as it looks at object inheritance and initialization more than anything else.

Here’s the short version:

__init__ is a method that gets called when initializing an instance. It’s not actually a constructor (that’s called __new__), but when you do something like

booking_form = BookingForm(room_choices) 

__init__ will be called after the constructor.

By calling super(BookingForm, self).__init__(*args, **kwargs) you allow initializations to bubble up the inheritance chain. In this case, you allow forms.Form to do all the initialization it needs to do, which includes defining the form and setting up the fields you defined.

After the fields are defined on the Form instance, you override the choices on the room field. If you’d try to switch those two lines so that the override takes place before the parent initialization, you’d get a KeyError as self.fields doesn’t exist at that point.

As for the params:

  • self is a reference to the current instance, that has to be passed to every instance method. This is how Python deals with instance methods (it’s the equivalent of this in Java)
  • room_choices is your param
  • *args and **kwargs are Python’s way of dealing with arbitrary parameters.

For example, if you’d have something like

def foo(param1):

and you called foo(1, 2, a=5) you’d get an error about the number of arguments. However, if you defined your method like this:

def foo(param1, *args, **kwargs):

and you called the same foo(1, 2, a=5), args would now be a list [1] and kwargs will be a dictionary {'a': 5} and you would obviously not get any errors.

*args and **kwargs are especially useful when you don’t want to care about all the parameters the parent method that you are overriding has – as it is in your case here, where forms.Form.__init__ has a whole bunch of parameters – which you don’t touch. You just add your parameter in front of them, and *args and **kwargs take any other potential parameter up the inheritance chain.

Leave a comment