> For the complete documentation index, see [llms.txt](https://appseed.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://appseed.gitbook.io/docs/content/tutorials/django-forms.md).

# Django Forms

This page explains how to **manage and validate a form in Django** Framework. We assume the audience has already a Django project up and running. For those that start from nothing, feel free to access the resources mentioned below and come back here once the content is understood:

* 👉 [How to install Django](/docs/content/tutorials/django-how-to-install.md) - simple, tested steps to install Django
* 👉 [Django for beginners](/docs/content/tutorials/django-for-beginners.md) - a comprehensive tutorial that covers the basics

> Topics covered by this tutorial

* ✅ Create a new Django app
* ✅ Define a new route
* ✅ Update the configuration to include the new application
* ✅ Code a simple form&#x20;
* ✅ Integrate the Form into a real page
* ✅ Update the controller to check the form is validated

The video presentation of this tutorial can be found on Github:

{% embed url="<https://www.youtube.com/watch?v=te350w1WwfQ>" %}
Django For Beginners - How to add a new form
{% endembed %}

## Create a new Application

> For this, we will use the `startapp` Django subcommand:

```bash
$ python manage.py startapp forms
```

> Add a simple view in forms - `forms/views.py`

```python
# File contents: forms/views.py

from django.shortcuts import render

from django.http import HttpResponse 

def index(request):                                  
    return HttpResponse("Hello Django - Forms")
```

> Define the routing for our new app - `forms/urls.py`

```python
from django.urls import path, re_path
from forms import views

urlpatterns = [

    # The home page
    path('forms/', views.index, name='home'),
]
```

> Update settings to include the new app - `config/settings.py`

```python
# File: config/settings.py (partial content)
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'forms',                           # <-- NEW
]
```

> Update routing - `config/urls.py`

```python
from django.contrib import admin
from django.urls import path, include  # <-- UPDATED to add 'include'    

urlpatterns = [
    path('admin/', admin.site.urls),
    path(""      , include("forms.urls")), # Forms app routing
]
```

Once we restart the project, the new route `/forms` should be visible:

![Django Forms -  A Hello-World type route](/files/-Mcc_Xb0SjKp4RN18B4V)

<br>

## Define a new form

Inside the newly created app, we need to create a `forms` file and define the new Form Class object.

```python
# File contents: forms/forms.py

from django import forms 
 
class HelloForm(forms.Form): 

    title   = forms.CharField() 
    message = forms.CharField() 
    email   = forms.EmailField(required=False) 
```

<br>

> Controller code - `forms/views.py`, the `index()` method

```python
from .forms import HelloForm

def index(request):                   
       
    if request.method == 'POST': 
        form = HelloForm(request.POST) 
        if form.is_valid(): 
            return HttpResponse("Form is valid")
            
    else: 
        form = HelloForm() 

    return render(request, 'hello.html', {'form': form}) 
```

<br>

> Update App configuration to include the new `Templates` folder, `core/settings.py` for AppSeed projects.

```python
FORMS_TEMPLATES = os.path.join(CORE_DIR, "forms/templates") # <-- NEW 

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [TEMPLATE_DIR, FORMS_TEMPLATES],            # <-- UPDATED LINE  
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'apps.context_processors.cfg_assets_root',
            ],
        },
    },
] 
```

<br>

> HTML page - defined in `forms/templates` folder:

```markup
<form action="" method="post"> 
    {\% csrf_token \%} <!-- NOTE: remove the Back Slash character -->

    <table> 
        {{ form.as_table }} 
    </table>      
    <br />
    <input type="submit" value="Submit"> 
</form> 
```

![Django Forms - Completed with user Data](/files/-Mcci1ek4mCT5IzHdygQ)

If all fields are provided, on submit, we should see the `Form is valid` message.

<br>

> Update the form with a new field `ID` (numeric type):

```python
from django import forms 
 
class HelloForm(forms.Form): 

    title   = forms.CharField()
    message = forms.CharField() 
    id      = forms.IntegerField()              # <-- NEW form field  
    email   = forms.EmailField(required=False) 
```

> The page server to the users is updated automaticaly to include the new field

![Django Forms - Integer Field Added](/files/-Mcck12lqQaax3R91ee6)

> Thanks for reading! For more topics, feel free to [contact](https://appseed.us/support) Appseed.

## Resources

* Read more about [Django](https://www.djangoproject.com/) (official docs)
* Start fast a new project using *development-ready* [Django Starters](https://appseed.us/admin-dashboards/django)
