jm.gunter jm.gunter - 1 month ago 9x
Python Question

Django model form doesn't populate when instance=object is set

I'm trying to populate a ModelForm with existing data if it exists or create a new instance if not. I've read the django docs and several questions here on Stack Overflow but I can't figure out why my form doesn't populate with the existing data. I'm sure I'm missing something simple, any help would be appreciated.


from django.forms import ModelForm, Textarea
from .models import Batch

class BatchForm(ModelForm):
class Meta:
model = Batch
fields = ('recipe', 'date', 'original_gravity', 'final_gravity', 'gravity_units', 'notes')
widgets = {'notes': Textarea(attrs={'cols': 40, 'rows': 10})}

in (notice the instance=batch argument, this should pre-populate the form correct?)

def batch_entry(request, batch_id):
if int(batch_id) > 0:
batch = get_object_or_404(Batch, id=batch_id)
form = BatchForm(request.POST, instance=batch)
context = {'BatchForm': form, 'batch': batch }
form = BatchForm()
context = {'BatchForm': form, 'batch': None }
return render(request, 'logger/batch_entry.html', context)

the batch_entry.html template:

{% if > 0 %}
<form action="{% url 'logger:batch_entry' %}" method="post">
{% csrf_token %}
<input type="submit" value="Submit">
{% else %}
<h1>New Batch</h1>
<form action="{% url 'logger:batch_entry' 0 %}" method="post">
{% csrf_token %}
<input type="submit" value="Submit">
{% endif %}
<form action="{% url 'logger:index' %}" method="post">
{% csrf_token %}
<input type="submit" value="Return to Index">


Because you're also passing request.POST. That is supposed to contain the submitted data, which would naturally override the values already in the instance; but since you're doing that on a GET, the POST data is empty, so your form is displayed empty.

Only pass request.POST into the form when the request is actually a POST.