Jonathan
Jonathan

Reputation: 539

How do I prepopulate a form with values from a database in Django?

I'm writing what should be a very simple todo app. The problem is that the edit view is giving me fits! I'm trying to populate a form with data from the database, and it's just not doing the right thing. I've tried the info from this page, but the translation into class-based views must have broken something, or I'm just not using the right kind of form.

Here's the code for the model:

class Todo(models.Model):
    id = models.AutoField(primary_key=True)
    todo = models.CharField(max_length=255, unique=True)
    todo_detail = models.TextField(default='')
    date_created = models.DateField(default=timezone.now())
    estimated_completion = models.DateTimeField(default=timezone.now())
    maybe_completed = models.BooleanField("Completed?", default=False)

    def __unicode__(self):
        return self.todo

The view code, the commented out bit is from the link:

class TodoEditView(FormView):
    model = Todo
    form_class = TodoEditForm
    template_name = 'todo_edit.html'

    #def get(self, request, *args, **kwargs):
    #    form = self.form_class()
    #    form.fields['todo'].queryset = Todo.objects.get(id=self.kwargs['pk'])
    #    form.fields['todo_detail'].queryset = Todo.objects.get(
    #        id=self.kwargs['pk'])
    #    form.fields['date_created'].queryset = Todo.objects.get(
    #        id=self.kwargs['pk'])
    #    form.fields['estimated_completion'].queryset = Todo.objects.get(
    #        id=self.kwargs['pk'])
    #    form.fields['maybe_completed'].queryset = Todo.objects.get(
    #        id=self.kwargs['pk'])
    #    template_vars = RequestContext(request, {
    #        'form': form
    #        })
    #    return render_to_response(self.template_name, template_vars)

    def get_context_data(self, **kwargs):
        context = super(TodoEditView, self).get_context_data(**kwargs)
        context['todo'] = Todo.objects.get(id=self.kwargs['pk'])
        return context

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            todo = request.POST['todo']
            todo_detail = request.POST['todo_detail']
            estimated_completion = request.POST['estimated_completion']
            date_created = request.POST['date_created']
            t = Todo(todo=todo, todo_detail=todo_detail,
                     estimated_completion=estimated_completion,
                     date_created=date_created)
            t.save()
            return redirect('home')

The form code:

class TodoEditForm(forms.ModelForm):

    class Meta:
        model = Todo
        exclude = ('id', )

And the template code:

{% extends 'todos.html'%}
{% block content %}
<form method="post" action="{% url 'add' %}">
<ul>
    {{ form.as_ul }}
    {% csrf_token %}
</ul>
{{todo.todo}}

</form>
{% endblock %}

What the heck am I doing wrong?

Upvotes: 0

Views: 982

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599540

You should use an UpdateView, not a FormView. That will take care of prepopulating your form.

Also note you don't need any of the logic in the post method - that is all taken care of by the generic view class.

Upvotes: 1

Related Questions