Forms Django
For this post we will create a Django project called "my_project", and app called "my_app", in app's views we will create a function called "index" tied to "my_app/" url. When the server receive a GET request will render a HTML file called "index.html" and when receive a POST request will render a HTML file called "user.html" sending as context the data received from "index.html".
"index.html" has a form with for send user data, including a photo to upload to the server.
Let's get started!
NOT using Django's Form class
Create the project "my_project" and the app "my_app"
We assume you has set a virtual environment and installed Django.
(env) path-to-the-project>django-admin startproject my_project
(env) path-to-the-project/my_project>py manage.py startapp my_app
Create the app's view
from django.shortcuts import render
def index(request):
if request.method=="POST":
# Handling the file uploaded
# The file is stored at static/images
file=request.FILES['photo']
with open('static/images/'+file.name, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
# Case POST request: Load the user information page
return render(request, 'my_app/user.html',
# Context
{
"name":request.POST.get('name'),
"username":request.POST.get('username'),
"email":request.POST.get('email'),
"photo":file.name,
})
# Case of GET request: Load the user registration form
return render(request, 'my_app/index.html')
Register the app's url
from django.urls import path
from . import views
app_name = 'my_app' # namespace for app's urls
urlpatterns = [
# path(url,function,name for this url)
# ex: /my_app/
path('', views.index, name='index')
]
Register the app's urls.py in project's urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('my_app/', include('my_app.urls')),
path('admin/', admin.site.urls),
]
HTML templates
my_app/templates/my_app/index.html
<!DOCTYPE html>
<html>
<head>
<title>User registration</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 col-lg-4">
<h1>User registration</h1>
<form class="" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email">
</div>
<div class="form-group">
<label for="photo">Photo:</label>
<input type="file" class="form-control-file" id="photo" name="photo">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
<!-- Include Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Notice the {% csrf_token %} instruction which injects in the form a hidden input that contains the CSRF token
my_app/templates/my_app/user.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>User information</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 col-lg-4">
<h1>User information</h1>
<form>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name" value="{{ name }}" disabled>
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" value="{{ username }}" disabled>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email" value="{{ email }}" disabled>
</div>
<div class="form-group">
<label for="photo">Photo:</label>
<img src="{% static 'images/' %}{{photo}}" class="img-fluid" alt="{{ photo }}">
</div>
</form>
<a href="{% url 'my_app:index'%}">Back</a>
</div>
</div>
</div>
<!-- Include Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Update project's settings
At "my_project/settings.py" we must add the static dir for loading static files as the image in "user.html":
STATIC_URL = 'static/'
STATICFILES_DIRS = ['static']
Using Django's Form class
Django has a class that helps us to work with forms:
Create the form
At "my_app/forms.py":
from django import forms
from django.forms.widgets import TextInput, EmailInput, ClearableFileInput
class UserForm(forms.Form):
name = forms.CharField(max_length=255, widget=TextInput(
attrs={'class': 'form-control', 'placeholder': 'Name'}))
username = forms.CharField(max_length=30, widget=TextInput(
attrs={'class': 'form-control', 'placeholder': 'Username'}))
email = forms.EmailField(widget=EmailInput(
attrs={'class': 'form-control', 'placeholder': 'Email'}))
photo = forms.ImageField(required=False, widget=ClearableFileInput(
attrs={'class': 'form-control-file'}))
Implement the form in the view
from django.shortcuts import render
from .forms import UserForm
def index(request):
if request.method=="POST":
# Handling the file uploaded
# The file is stored at static/images
if request.FILES:
file=request.FILES['photo']
with open('static/images/'+file.name, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
# Case POST request: Load the user information page
form = UserForm(request.POST)
# check whether it's valid:
if form.is_valid():
return render(request, 'my_app/user.html',{'form':form,'photo':file.name})
return render(request, 'my_app/index.html',{'form':form})
# Case of GET request: Load the user registration form
form = UserForm()
return render(request, 'my_app/index.html',{'form':form})
Adapt the HTML templates
my_app/templates/my_app/index.html
<!DOCTYPE html>
<html>
<head>
<title>User registration</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 col-lg-4">
<h1>User registration</h1>
<form class="" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="name">Name:</label>
{{ form.name }}
</div>
<div class="form-group">
<label for="username">Username:</label>
{{ form.username }}
</div>
<div class="form-group">
<label for="email">Email:</label>
{{ form.email }}
</div>
<div class="form-group">
<label for="photo">Photo:</label>
{{ form.photo }}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
<!-- Include Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
my_app/templates/my_app/user.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>User information</title>
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-8 col-lg-4">
<h1>User information</h1>
<form>
<div class="form-group">
<label for="name">Name:</label>
{{ form.name }}
</div>
<div class="form-group">
<label for="username">Username:</label>
{{ form.username }}
</div>
<div class="form-group">
<label for="email">Email:</label>
{{ form.email }}
</div>
<div class="form-group">
<label for="photo">Photo:</label>
<img src="{% static 'images/' %}{{photo}}" class="img-fluid" alt="{{ photo }}">
</div>
</form>
<a href="{% url 'my_app:index'%}">Back</a>
</div>
</div>
</div>
<!-- Include Bootstrap JS -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
Thanks for reading :)
I invite you to continue reading other entries and visiting us again soon.