Django forms
When we work with input from users in Django, we almost always want to use forms. I'm not just talking about HTML forms now, but a feature from Django.
By doing this, we keep best pratices for security and similar. The first thing we can do is to create a new file called "forms.py" in the "task" app folder. We could actually call this whatever we want, but forms.py makes sense and it's best practice to call it that :-)
The file should look like this:
from django.forms import ModelForm
from .models import Task
class TaskForm(ModelForm):
class Meta:
model = Task
fields = ('title', 'description', 'is_done', 'category')
This little snippet of code gives us a lot of functionality. Like valitation, it helps us store the info correctly, it helps us show the form and similar.
In this case, we use something called a "ModelForm". A ModelForm takes a model (Taks) and a list of fields. Next step now is to do some changes to the front page view:
from django.shortcuts import render
from .forms import TaskForm # New, 1
from .models import Task
from category.models import Category
def frontpage(request):
form = TaskForm() # New, 2
title = 'This is a variable'
tasks = Task.objects.all()
categories = Category.objects.all()
return render(request, 'task/frontpage.html', {'title': title, 'tasks': tasks, 'categories': categories, 'form': form}) # Changed, 3
1. First, we import the form we just created.
2. Then, we create a new instance of it.
3. Then to make it available in the templat, we add it to the context list.
Next step then is to show it in the template. Open up frontpage.html and make it look like this:
{% extends 'task/base.html' %}
{% block content %}
<div class="frontpage">
<h1>{{ title }}</h1>
<div class="columns">
<div class="column is-8">
<h2>Tasks</h2>
<!-- New -->
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<button>Submit</button>
</form>
<!-- End -->
{% for task in tasks %}
<div>
<p>{{ task.title }}</p>
</div>
{% endfor %}
</div>
<div class="column is-4">
<h2>Categories</h2>
{% for category in categories %}
<div>
<p>
<a href="{% url 'category_detail' category.id %}">{{ category.title }}</a>
</p>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
When we use "post" as the request method for a form, we always need to add something called a csrf_token. This is a security step from Django. This is a way to make it impossible/harder to make the request from other sites.
Then, to print the form, we just say {{ form.as_p }}.
This will render the form fields as paragraphs. You could also try {{ form.as_table }} if you wanted to.
It doesn't look very pretty, but it could be customized if you wanted to :-)
Submitting the form
If you try the form now, nothing would happen. Because we don't do anything with it in the view, we just created an empty instance of it. We need to check if the form has been submitted, if it's valid and similar.
from django.shortcuts import render
from .forms import TaskForm
from .models import Task
from category.models import Category
def frontpage(request):
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save()
else:
form = TaskForm()
title = 'This is a variable'
tasks = Task.objects.all()
categories = Category.objects.all()
return render(request, 'task/frontpage.html', {'title': title, 'tasks': tasks, 'categories': categories, 'form': form})
Now we added a bunch of new lines here. But it's almost a bit self explainable. First, we check if the method of the request is POST. If so, we know that the form has been submitted.
And if if has been submitted, we want to create an instance of the form where we pass in the POST data. When that's done, we check if it's valid and save it. If there are errors, Django will show the errors in the template automatically.
If it's not a POST request, we just create an empty instance of the form to show it.
Summary
We have now successfully made it possible to add data to our project. Next step now is to make it possible to edit tasks. So tomorrow, we will keep learning about Django forms.
Table of contents
- 1. Introduction
- 2. Installation and setup
- 3. How things work
- 4. The first Django app
- 5. Your first view
- 6. Your first template
- 7. Testing our site
- 8. Extending templates
- 9. Your first model
- 10. The admin interface
- 11. Showing contents from the model
- 12. Another app (category)
- 13. Connecting two models
- 14. Show list of categories
- 15. Category detail page
- 16. Separate url files and why
- 17. Adding tasks in the front end