# Using HTML form to alter database

**URL:** <https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080>\
**Category:** Using Django\
**Created:** [April 22, 2020, 1:33pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080 "2020-04-22T13:33:17Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [April 22, 2020, 1:33pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/1 "2020-04-22T13:33:18Z")

</div>

Hi everyone !

I would like to alter my database using the following HTML form :

```
<form id="newProductForm" method="POST">

        <label for="product_name">Product Name : </label>
        <input type="text" name="product_name">

        <label for="product_description">Description : </label>
        <input type="text" name="product_description">

        <label for="product_price">Price : </label>
        <input type="text" name="product_price">

        <div id="newProductForm_controls">
            <input type="submit" value="Confirm">
            <input type="button" value="Cancel" onclick="cancel()">
        </div>

</form>

```

And here is my “Product” model :

```
class Product(models.Model):
    product_name = models.CharField(max_length=80)
    product_description = models.CharField(max_length=100)
    product_quantity_available = models.PositiveIntegerField(default=0)
    product_price = models.PositiveIntegerField(default=0)

```

How to proceed ?

Thank you in advance 🙂

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 22, 2020, 4:46pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/2 "2020-04-22T16:46:39Z")

</div>

If you haven’t already done so, I **strongly** encourage you to work through the [Django Tutorial](https://docs.djangoproject.com/en/3.0/intro/tutorial01/). It’ll help you get started in your understanding of how Django works with forms (among other important topics).

From there, you’ll probably be interested in reading more about [Forms](https://docs.djangoproject.com/en/3.0/topics/forms/) to see more of the different features available.

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [April 25, 2020, 12:15am UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/3 "2020-04-25T00:15:26Z")

</div>

Hi @KenWhitesell !

Thank you for your answer 😃

I indeed took the time to read the said tutorials. What I understood is that the best way to create a HTML form able to alter the database is to create a Django ModelForm (as the models.py already contains the fields).

Yet, I don’t know how to “organize” this Django form.

Let’s take a more simple example with a absic ToDo app :

models.py

```
from django.db import models

    class Task(models.Model):
        task_name = models.CharField(max_length=40, default="")
        task_description = models.CharField(max_length=140, default="")

        def __str__ (self):
            return self.task_name 

```

forms.py

```
from django import forms
from django.forms import ModelForm
from .models import Task

class TaskForm(ModelForm):
    class Meta:
        model = Task
        fields = ["task_name","task_description"]

```

views.py

```
from django.shortcuts import render
from .forms import TaskForm
from .models import Task

def index(request):

    if(request.method=="POST"):
        form = TaskForm(request.POST)

        if form.is_valid():
            form.save()

    else:
        form = TaskForm()

    task_list = Task.objects.all()
    context = {
        "form":form,
        "task_list":task_list, 
        }

    return render(request, "tasks/index.html", context)

```

index.html

```
{% block page_content %}
    <h2>To Do</h2>

    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">

    <div id="tasks_area">
        {% for task in task_list %}

            <div id="task">
                <p>Name : {{ task.task_name }} </p>
                <p>Description : {{ task.task_description }} </p>

                <div id="task_controls">
                    <input type="button" value="Update">
                    <input type="button" value="Delete">
                </div>

            </div>

        {% endfor %}

    </div>

{% endblock %}

```

The issue is that I can’t really “organize” the HTML {{ form }} tags as I only refer to it as {{ form }}, how can I add a placeholder ? Breaklines ?

Thank you in advance for your help

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 25, 2020, 12:35am UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/4 "2020-04-25T00:35:34Z")

</div>

Great! Now you can move on to [Working with Form Templates](https://docs.djangoproject.com/en/3.0/topics/forms/#working-with-form-templates), which includes the section on [Rendering fields manually](https://docs.djangoproject.com/en/3.0/topics/forms/#rendering-fields-manually).

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [April 25, 2020, 2:26pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/5 "2020-04-25T14:26:06Z")

</div>

Hi @KenWhitesell,

I tried to follow the tutorials but when I use :

```
{% csrf_token %}
<form id="submit_area" action="" method="POST">
    <input id="{{ form.task_name.id_for_input }}" type="text" placeholder="Type in your new task">
    <input type="submit" value="Submit">
</form> 

```

I get a CSRF error…

What I wanted to do is to link the first input with {{ form.task\_name.id\_for\_input }} to the task\_name Form Field but it doesn’t work

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 25, 2020, 2:57pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/6 "2020-04-25T14:57:11Z")

</div>

I’m just curious here - have you tried searching the Django documentation for CSRF?

Generally speaking, it’s going to be a lot quicker for you if you search there first before making a post here. If you can’t find something, or don’t understand what you’re reading, we’re more than happy to help. But this shouldn’t be your first stop for generic errors that are documented elsewhere.

Ken

---

<div class="post-metadata">

**Author:** ![mblayman](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/mblayman/32/101_2.png) [@mblayman](https://forum.djangoproject.com/u/mblayman)\
**Post date:** [April 25, 2020, 8:28pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/7 "2020-04-25T20:28:47Z")

</div>

The problem is that `{% csrf_token %}` must go _inside_ the `form` tag. That template tag will expand into an `input` tag with type of `hidden`. Because you have the template tag outside of the `form` tag, your page is not sending the token with the form submission and is rejected by Django because it can’t complete the CSRF verification.

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [April 25, 2020, 10:42pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/8 "2020-04-25T22:42:14Z")

</div>

Hi @mblayman !

Yes, indeed, thank you for your explanation 🙂

It works now but I don’t know how to alter the database here :

```
<form id="submit_area" action="" method="POST">
    {% csrf_token %}
    <input id="{{ form.task_name.id_for_input }}" type="text" placeholder="Type in your new task">
    <input type="submit" value="Submit">
</form>

```

I don’t understand why (and trust me I’ve read the Django form doc) because I wrote the save method in my views.py file :

```
from django.shortcuts import render
from .forms import TaskForm
from .models import Task

# Create your views here.
def index(request):
if(request.method=="POST"):
    form = TaskForm(request.POST)
    if form.is_valid():
        form.save()
else:
    form = TaskForm()

task_list = Task.objects.all()
context = {
    "form":form,
    "task_list":task_list, 
    }
    
return render(request, "tasks/index.html", context)

```

So when I hit the submit button, I should normally have a new model entry in my db but nope…

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [April 26, 2020, 12:09am UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/9 "2020-04-26T00:09:45Z")

</div>

Ok, you’re trying to render your data entry field manually rather than rendering the form you’re creating.  
You’re creating your form as TaskForm, but you’re not rendering _that form_ (or the individual form fields) in your template. Also, your view doesn’t provide any means of showing errors that may appear, so the errors generated by your form are hidden.

If you make your form block in your template look like this:

```auto
<form id="submit_area" action="" method="POST">
    {% csrf_token %}
    {{ form.task_name}}
    {{ form.task_description }}
    <input type="submit" value="Submit">
</form>

```

It should work.

(Specifically what was happening was that you weren’t rendering your form, so the form didn’t know how to bind the values being returned by the browser - and so both database fields were null. Your form was generating errors on null values trying to be saved in non-null fields. Even if you would have rendered the task\_name correctly, you still would have had an error on the task\_description field because it wasn’t in your form at all.)

Ken

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [April 26, 2020, 11:56pm UTC](https://forum.djangoproject.com/t/using-html-form-to-alter-database/2080/10 "2020-04-26T23:56:05Z")

</div>

Hi @KenWhitesell, thanks it works now !
