Django - KeyError on formset form field



So I'm getting a KeyError, every time I try to submit a formset.
I asked a similar question before here, and the solution seemed to work for a while, but now I get the above mentioned KeyError.
Code and Trace below:


class CodingForm(forms.Form):
    NATIONAL = 0
    REGIONAL = 1
    LOCAL = 2
    NA = 99
        (NA, 'No Report'),
        (NATIONAL, 'National'),
        (REGIONAL, 'Regional'),
        (LOCAL, 'Local'),

    NO_VIO = 0
    PROP_DMG = 1
    INJ = 2
    KILL = 3

    PART_VIO = (
        (NA, 'No Report'),
        (NO_VIO, 'No Violence'),
        (PROP_DMG, 'Property Damage'),
        (INJ, 'People Injured'),
        (KILL, 'People Killed'),

    NO_PRES = 0
    PRES = 1
    INT = 2
    LETHAL_INT = 3

    SEC_ENG = (
        (NA, 'No Report'),
        (NO_PRES, 'No Presence'),
        (PRES, 'Presence'),
        (INT, 'Intervention'),
        (LETHAL_INT, 'Lethal Intervention'),

    event_date = forms.DateField(required=False)
    location = GeonamesChoiceField(queryset=Geonames.objects.all(), required=False)
    actors = forms.CharField(max_length=100, required=False)
    num_participants = forms.CharField(max_length=200, required=False)  
    issue = forms.CharField(max_length=200, required=False)
    side = forms.NullBooleanField('Side')
    scope = forms.TypedChoiceField(choices=SCOPE_CHOICES, coerce=int, empty_value=None)
    part_violence = forms.TypedChoiceField(choices=PART_VIO, coerce=int, empty_value=None)
    sec_engagement = forms.TypedChoiceField(choices=SEC_ENG, coerce=int)
    relevance = forms.NullBooleanField('relevance')

    def clean(self):
            cleaned_data = self.cleaned_data
            event_date = cleaned_data.get("event_date")
            location = cleaned_data.get("location")

            if event_date and location:
                cleaned_data['relevance'] = True
                print cleaned_data["relevance"]
                cleaned_data['relevance'] = False

            return cleaned_data


def assignment(request, pk):
"""View for each assignment"""
if request.user.is_authenticated():

    #### Get correct articles
    assignment = get_object_or_404(Assignment, pk=pk)
    country =
    start_date = assignment.start_date
    end_date = assignment.end_date
    articles = Article.objects.filter(cowcode=country).filter(pubdate__range=(start_date,end_date))

    #### Pagination ####
    paginator = Paginator(articles, 1)
    page = request.GET.get('page')
        articles =
    except PageNotAnInteger:
        articles =
    except EmptyPage:
        articles = paginator(page(paginator.num_pages))

    # Check if on first page and enable redirect
    if page is None:
        current_page = 1
        current_page = page
    redirect_to = "?page=%s" % current_page

    CodingFormSet = formset_factory(CodingForm, extra=0)
    formset = CodingFormSet(request.POST or None, prefix="coding_form")

    location_queryset = Geonames.objects.filter(cowcode=country).order_by('name')
    for form in formset.forms:
           form.fields['location'].queryset = location_queryset

    ##### Check if coder wants to go to next page or stay
    if "coding_form_next" in request.POST:
        process_form(formset, request, current_page, paginator)
        current_page = int(current_page) + 1
        redirect_to = "?page=%s" % current_page
        return HttpResponseRedirect(redirect_to)
    elif "coding_form_save" in request.POST:
        process_form(formset, request, current_page, paginator)
        redirect_to = "?page=%s" % current_page
        return HttpResponseRedirect(redirect_to)

    print ERROR
return render(request, 'coding/assignment.html', 

def process_form(formset, request, current_page, paginator):
if formset.is_valid():
    for form in formset.forms:
        form = form.cleaned_data

        if form['relevance'] == False:
        elif form['relevance'] == True:

            event_form = EventRecordForm()

            event =
            event.article =[0]
            event.coder = request.user
            event.last_updated =
            event.event_date = form["event_date"]
            event.location = form["location"]
            event.actors = form["actors"]
            event.num_participants = form["num_participants"]
            event.issue = form["issue"]
            event.side = form["side"]
            event.scope = form["scope"]
            event.part_violence = form["part_violence"]
            event.sec_engagement = form["sec_engagement"]

    ##### Add info on who worked on the article when
    history_form = ArticleHistoryForm()
    article_history =
    article_history.article =[0]
    article_history.coder = request.user
    article_history.last_updated =


<div id="coding">
<div id="coding-inner">
    {% with formset.empty_form as form %}
    <div id="empty_form" style="display:none">
        <table border="0" cellspacing="5" cellpadding="5">
                <td>{{ form.event_date.label_tag}}</td>
                <td>{{ form.event_date}}</td>
                <td>{{ form.location.label_tag }}</td>
                <td><div class="location_wrapper">{{ form.location }}</div></td>
                <td>{{ form.actors.label_tag }}</td>
                <td>{{ form.actors }}</td>
                <td>{{ form.num_participants.label_tag }}</td>
                <td>{{ form.num_participants }}</td>
                <td>{{ form.issue.label_tag }}</td>
                <td>{{ form.issue }}</td>
                <td>{{ form.side.label_tag }}</td>
                <td>{{ form.side }}</td>
                <td>{{ form.scope.label_tag }}</td>
                <td>{{ form.scope }}</td>
                <td>{{ form.part_violence.label_tag}}</td>
                <td>{{ form.part_violence}}</td>
                <td>{{ form.sec_engagement.label_tag }}</td>
                <td>{{ form.sec_engagement }}</td>
                <td>{{ form.relevance.label_tag }}<td>
                <td>{{ form.relevance }}<td>
    {% endwith %}
    <form action="" method="post" accept-charset="utf-8" id="form"> 
        {% csrf_token %}
        <div class="form-container"></div>
        {{ formset.management_form }}
        <div id="form-nav">

            <div id="save-stay">
                <input type="submit" name="coding_form_save" value="Save">
            <div id="save-next">
                <input type="submit" name="coding_form_next" value="Save &#38; Next">



And the Trace:

Request Method: POST
Request URL:

Django Version: 1.5
Python Version: 2.7.2
Installed Applications:
Installed Middleware:

File "/Users/lukaskawerau/.virtualenvs/MMAD/lib/python2.7/site-packages/django/core/handlers/" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/lukaskawerau/Dropbox/Coding/mmad/app/mmad/coding/" in assignment
  179.             process_form(formset, request, current_page, paginator)
File "/Users/lukaskawerau/Dropbox/Coding/mmad/app/mmad/coding/" in process_form
  36.             if form['relevance'] == False:

Exception Type: KeyError at /coding/assignment/1/
Exception Value: 'relevance'

What am I doing wrong? I've tried everything I could think of, but nothing works.
Any help is hugely appreciated!

Update: I looked at local vars again, and notices that form is empty:

formset <django.forms.formsets.CodingFormFormSet object at 0x10eb9dd10>
form    {}

Why would that be?

Update 2: The problem was a different thing entirely: The JavaScript plugin I was using was messing with the HTML "name" tag of my inputs, so Django only saw an empty form.
I'm accepting @Francis answer, because it was the most detailed and still helpful. My bounty also shouldn't go to waste.
What do we learn from this? Check your JS.

3 Answers: 

I haven't set up this example in my test project, but something that strikes me as a possible problem is this:

relevance = forms.NullBooleanField('relevance')

The NullBooleanField allows NULL as one of the options. I wonder if the form is seeing a NULL/None and removing the key/value from the cleaned_data dict...

either way, I'd call the form's super's clean method and start from there...

def clean(self):
    #this line is kinda important
    cleaned_data = super(CodingForm, self).clean()

    event_date = cleaned_data.get("event_date")
    location = cleaned_data.get("location")

    if event_date and location:
        cleaned_data['relevance'] = True
        print cleaned_data["relevance"]
        cleaned_data['relevance'] = False

    return cleaned_data

additionally wrap calls to dict elements like this to prevent key errors

if 'relevance' in form:
    if form['relevance'] == False:
    elif form['relevance'] == True:


    if form['relevance'] == False:
    elif form['relevance'] == True:
except KeyError, e:

It should be form.fields['relevance'] in place of form['relevance'].


There's an error in your clean method. It should start with

cleaned_data = super(CodingForm, self).clean()

like the example in the docs.