title: Over-Ride __init__: Extending Forms (Python/Django)
body: <p>Struggling to figure out how to Over-Ride the <code>__init__()</code> method in my Django Form to include additional values from the database. I have a group of photographers that I am trying to list as a form option for the user. Afterwards, the user's photographer selection will be added (along with other information) to the database as an instantiation of a new model.</p>
  
  <p>This is a continuation, or elaboration, of my other <a href="https://stackoverflow.com/questions/11548992/adding-values-to-complex-django-view">Current Question</a>. @Rob Osborne has given me some great advice helping me understand how to extend <code>BaseForm</code>, but I still cannot get my code to execute. The linked question lists my models, form, and views, if you are interested. While I understand that using ModelForm is easier and more documented, I must use BaseForm in this instance.</p>
  
  <p>Here is what I have:</p>
  
  <pre><code>class AForm(BaseForm):
      def __init__(self, data=None, files=None, instance=None, auto_id='id_%s',
                   prefix=None, initial=None, error_class=ErrorList,
                   label_suffix=':', empty_permitted=False):
  
          self.instance = instance
          object_data = self.instance.fields_dict()
          self.declared_fields = SortedDict()
          self.base_fields = fields_for_a(self.instance)
  
          BaseForm.__init__(self, data, files, auto_id, prefix, object_data,
                        error_class, label_suffix, empty_permitted)
          self.fields['photographer'].queryset = Photographer.objects.all()
  
      def save(self, commit=True):
          if not commit:
              raise NotImplementedError("AForm.save must commit it's changes.")
  
          if self.errors:
              raise ValueError(_(u"The Form could not be updated because the data didn't validate."))
  
          cleaned_data = self.cleaned_data
  
          # save fieldvalues for self.instance
          fields = field_list(self.instance)
  
          for field in fields:
              if field.enable_wysiwyg:
                  value = unicode(strip(cleaned_data[field.name]))
              else:
                  value = unicode(cleaned_data[field.name])
  </code></pre>
  
  <p>Using the above code results in a <code>KeyError at 'photographer'</code>. </p>
  
  <p>I appreciate any ideas / comments on how to resolve this KeyError so that I can get the <code>photographer</code> values into my form. Thank you!</p>
  
  <hr>
  
  <p>EDIT:</p>
  
  <p>Trying to use super, as recommended by @supervacuo, but still getting a <code>KeyError at photographer</code> as before:</p>
  
  <pre><code>class AForm(BaseForm):
      def __init__(self, data=None, files=None, instance=None, auto_id='id_%s',
               prefix=None, initial=None, error_class=ErrorList,
               label_suffix=':', empty_permitted=False):
  
          super(AForm, self).__init__(data, files, auto_id, prefix, object_data,                         error_class, label_suffix, empty_permitted)
          self.fields['photographer'].queryset = Photographer.objects.all()
  </code></pre>
  
  <p>What could I be missing that is generating the KeyError? Thanks for any advice.</p>
  
  <hr>
  
  <p>EDIT 2: adding <code>fields_dict()</code></p>
  
  <p>from models.py</p>
  
  <pre><code>class A(models.Model):
      category = models.ForeignKey(Category)
      user = models.ForeignKey(User)
  
      def fields_dict(self):
          fields_dict = {}
          fields_dict['title'] = self.title
  
          for key, value in self.fields():
              fields_dict[key.name] = value.value
  
          return fields_dict
  </code></pre>
  
  <p>Thanks for any advice.</p>
  
  <hr>
  
  <p>EDIT 3: (edited <code>class AForm</code> above in the initial question as well, to include more information)</p>
  
  <pre><code>def fields_for_a(instance):
      fields_dict = SortedDict() 
      fields = field_list(instance)
  
      for field in fields:
          if field.field_type == Field.BOOLEAN_FIELD:
              fields_dict[field.name] = forms.BooleanField(label=field.label, required=False, help_text=field.help_text)
          elif field.field_type == Field.CHAR_FIELD:
              widget = forms.TextInput
              fields_dict[field.name] = forms.CharField(label=field.label, required=field.required, max_length=field.max_length, help_text=field.help_text, widget=widget)
  
              fields_dict[field.name] = field_type(label=field.label,
                                               required=field.required,
                                               help_text=field.help_text,
                                               max_length=field.max_length,
                                               widget=widget)
  
      return fields_dict
  </code></pre>
  
  <hr>
  
  <p>EDIT 4: def fields(self). from models.py:</p>
  
  <pre><code>    def fields(self):
          fields_list = []
          fields = list(self.category.field_set.all())
          fields += list(Field.objects.filter(category=None))
  
          for field in fields:
              try:
                  fields_list.append((field, field.fieldvalue_set.get(ad=self),))
              except FieldValue.DoesNotExist:
                  pass  # If no value is associated with that field, skip it.
  
          return fields_list
  
      def field(self, name):
          if name == 'title':
              return self.title
          else:
              return FieldValue.objects.get(field__name=name, ad=self).value
  </code></pre>