Django ModelForm – Creating Forms using Django Models

Django ModelForm - Creating Forms using Django Models

Django ModelForm is a class that converts a model into a Django form directly. If you’re creating a database-driven project, you’ll almost certainly have forms that correspond to Django models. ModelForms in Django is an utility class that lets you generate a Form class from an existing Django model.

It appears to be more difficult to implement than it actually is.

Create a Django Model Which ModelForm Will Use

Add a model to models.py

demosite > main > models.py

from django.db import models # Create your models here. class Movie(models.Model): movie_title = models.CharField(max_length=150) release_year = models.IntegerField() director = models.CharField(max_length=100) movie_poster = models.ImageField(upload_to='images/', None=True) movie_plot = models.TextField() def __str__(self): return self.movie_title

The preceding example comes from the book How to Use Django Models. There are CharFields, IntegerFields, ImageFields, and TextFields in the model.

The code at the bottom returns the movie’s title as the admin’s display name, making each model object easier to recognise.

Configure Django Website To Support Media Uploads

demosite > demosite > settings.py

MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Code language: JavaScript (javascript)

If your models contain an ImageField or FileField, include a URL for Django media file uploads in the settings.

demosite > demosite > urls.py

from django.contrib import admin from django.urls import path, include from django.conf import settings #add this from django.conf.urls.static import static #add this urlpatterns = [ path('admin/', admin.site.urls), path('', include ('main.urls')), ] if settings.DEBUG: #add this urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Code language: PHP (php)

Also, in the demosite > urls.py file, add a URL path for the media files. You’ll see that these settings are solely for testing.

To serve media files in production, follow these instructions

Install Pillow

pip install Pillow

For media uploading, you’ll also need to install Pillow.

Run Migrations

py manage.py makemigrations py manage.py migrate
Code language: CSS (css)

To develop the Movie model, you’ll also need to make migrations and migrate to apply the migrations to the database.

Register the model in the Django admin.py

demosite > main > admin.py

from django.contrib import admin from .models import Movie admin.site.register(Movie)
Code language: JavaScript (javascript)

Now that the model has been uploaded to the database, you may see and change it via the Django administration interface by registering it in the admin.py file.

To access the admin page, you’ll need a Django superuser account.

Create a Django ModelForm

Create a forms.py

demosite > main > (New File) forms.py

from django import forms # Create your forms here.
Code language: PHP (php)

Because Django does not include a forms.py file, you must create one in the same directory as the models.py file, mysite > main.

Then, at the top of the model, you may import forms from Django.

Rather than declaring Django form fields like forms, we’ll do it now.

Let’s import our current Model, CharField.

Because, as you may have observed, the model fields are the exact fields that we require for the form.

Create a ModelForm

demosite > main > forms.py

from django import forms from .models import Movie # Create your forms here.
Code language: PHP (php)

Please notice that the official Django documentation imports ModelForm from django.forms and places ModelForms in the models.py file. Let’s simply add my ModelForms to the forms.py file instead.

I prefer this way since it’s easier for me to refer to the forms.py file whenever I need a form.

demosite > main > forms.py

from django import forms from .models import Movie # Create your forms here. class MovieForm(forms.ModelForm): class Meta: model = Movie fields = ('movie_title', 'release_year', 'director', 'movie_poster', 'movie_plot')

For your form, create a MovieForm class. The ModelForm’s functionality may be changed using the Meta class. Indicate the model that your fields are generated from, as well as the fields that you want to use from that model.

You may choose to include all of the fields or just a few.

Create a Django Template To Utilize The Form

Render the ModelForm and Model objects

demosite > demosite > views.py

from django.shortcuts import render, redirect from .models import Movie from .forms import MovieForm from django.contrib import messages # Create your views here. def homepage(request): if request.method == "POST": movie_form = MovieForm(request.POST, request.FILES) if movie_form.is_valid(): movie_form.save() messages.success(request, ('Your movie was successfully added!')) else: messages.error(request, 'Error saving form') return redirect("main:homepage") movie_form = MovieForm() movies = Movie.objects.all() return render(request=request, template_name="main/home.html", context={'movie_form':movie_form, 'movies':movies})
Code language: PHP (php)

Add an if condition for the form submission to your views.py file. Make sure to include a request. If you choose FILES as the file data source, your picture will not be saved to the form.

Save the form if it is correct. If the form is both valid and incorrect, you may select to display a Django message.

Because the form is a MovieForm, saving it now creates a new model object in the Movie model. This makes rendering the form and model objects in the next stage a breeze.

Render the ModelForm and Model objects

demosite > main > (New Folder) templates > (New Folder) main > (New File) home.html

<!DOCTYPE html> <html> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <title>Django ModelForms</title> </head> <body> {% load crispy_forms_tags %} <div class="container"> <!--Django Model Form--> <h2 class="my-4">Add a new movie</h2> <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{movie_form|crispy}} <button class="btn btn-primary my-4" type="submit">Submit</button> </form> <!--Django Model--> <h2 class="my-4">Movies</h2> <div class="row"> {% for m in movies %} <div class="col-lg-4 col-md-6 col-sm-12 pb-4"> <div class="card h-100 p-4"> <img src="{{ m.movie_poster.url }}" class="card-img-top" alt="{{ m.movie_title}}"> <h4>{{m.movie_title}}</h4> <p class="text-muted">{{m.release_year}} | {{m.director}}</p> <p>{{m.movie_plot}}</p> </div> </div> {% empty %} <p>No movies added.</p> {% endfor %} </div> </div> <!-- Option 1: Bootstrap Bundle with Popper --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> </body> </html>
Code language: HTML, XML (xml)

Let’s get started on the Django template. This template will render the MovieForm and the Movie model objects as cards, among other things.

The Bootstrap 5.0.2 CDN is used in this template.

IMPORTANT: enctype="multipart/form-data" must be included to form. This is done to guarantee that uploaded files, such ImageField and FileField, are encoded before being sent to the server.

I’d also want to note out that if the array is empty or not found, you may use the percent empty percent template element to show content.

Result

Conclusion

I believe ModelForm is a very powerful helper class provided to us by Django. Effectively utilizing the class can enable us to streamline our form development process, and make integrating forms with Django models extremely easy.

In this article, we took a look at how to work with ModelForms in Django. We took a look at creating, rendering and working with Django ModelForms. As always, If you have found this article useful do not forget to share it and leave a comment if you have any questions. Happy Coding

%d bloggers like this: