Dynamic forms with Django and Vue.js

A step-by-step guide to implementing dynamic forms

Fatime Selimi
The Startup
5 min readFeb 25, 2020

--

In this example, we’re going to build a web application to manage an author and their books using Django nested formsets. Once we are done building this web application it will look something like this: https://fatse.pythonanywhere.com/.

The full code for this web application can be found in my GitHub profile.

Building dynamic forms using Django forms is not ideal especially when you need the form to dynamically change before the user saves the form. In this example, we want the user to add as many books as they want without having full-page refreshes every time they add a book. To achieve this dynamic behavior, I’ve used Vue.js in conjunction with Django nested formsets.

Technologies used:

Python 3.7.6
Django 2.2.5
Vue.js 2.2

We will build our application by following these steps:

  1. Create a new virtual environment
  2. Install Django
  3. Create a new Django project and a new Django application
  4. Create our models
  5. Create our modelforms and nested inlineformsets
  6. Implement our views
  7. Build our templates, add and use Vue.js to create our dynamic forms
  8. Create our URLs
  9. Run our application

1. Let’s start by creating a new virtual environment. By creating a new virtual environment we will isolate our Django setup on a per-project basis, thus any change that we make to our project will not affect other projects that we might be also developing.

So, let’s create a new directory in which we will create our virtual environment.

mkdir django_vuejs_tutorialcd django_vuejs_tutorial

Once we have created and are inside the new directory we are ready to create our new environment by running this command:

python3 -m venv env

And finally, we need to activate the new virtual environment like this:

source env/bin/activate

2. Since we have activated our virtual environment we can install our preferred Django version. In this example, we will install Django 2.2.5.

(env) ~/django_vuejs_tutorial$ pip install Django==2.2.5

3. Now we can create a new Django project. We will call this project django_vuejs, and we will create it by running the following:

(env) ~/django_vuejs_tutorial$ django-admin startproject django_vuejs

Next, we will create a new Django application. We will call this application django_formset_vuejs and we will create it like this:

(env) ~/django_vuejs_tutorial$ python manage.py startapp django_formset_vuejs

After we have successfully created our new application we have to add it to INSTALLED_APPS inside settings.py file.

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'django_formset_vuejs',
]

At this point our project tree should look like this:

django_vuejs_tutorial
├── django_formset_vuejs
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
├── django_vuejs
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── myvenv

4. Inside django_formset_vuejs you can see a file called models.py. Let’s add our first models in that file.

We will create three models:

  1. AuthorContainer
  2. Author
  3. Book

We will use these models to build our inlineformset for handling all authors for AuthorContainer or all Books of an Author.

After we have created our models we need to run makemigration and migrate commands to create our new models in the database.
We can run these commands like this:

(env) ~/django_vuejs_tutorial$ python manage.py makemigrations(env) ~/django_vuejs_tutorial$ python manage.py migrate

5. Now we can add our modelforms inside django_formset_vuejs/forms.py. In this file we will define our Django formsets as well.

First, we will create an inlineformset like the lines of code below:

BookFormset = inlineformset_factory(models.Author, models.Book, form=BookForm, can_delete=True, extra=0)

By using the above inlineformset we can handle all books for an author. The argument can_delete lets you create a formset with the ability to select forms for deletion and the number of empty forms that is displayed is controlled by the extra parameter.

Further, we will create a basic inlineformset and attach to it a nested formset for BookFormset. The superclass BaseInlineFormSet defines the add_fields() method which is in charge of adding the fields for each form in a formset. In this method, we will write the logic to associate the nested BookFormset.

6. We’re ready to implement our views in django_formset_vuejs/views.py and handle formset and nested formsets in our views.

We are calling formset.is_valid() to validate the forms when the page is submitted and we are overriding it to add validation for the nested formsets as well.

7. We should first create a directory inside django_formset_vuejs application with the name templates, and then inside templates directory, we should create another directory with the name of our application, that is django_formset_vuejs.
Now let’s add two templates, home.html and author.html, inside django_formset_vuejs.

Our project tree now looks like this:

django_vuejs_tutorial
├── django_formset_vuejs
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── 0001_initial.py
│ ├── migrations
│ │ └── __init__.py
│ ├── templates
│ │ └── django_formset_vuejs
│ │ └── home.html
│ │ └── author.html
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── django_vuejs
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── myvenv

In home.html we will put the code for our base template with our styles, scripts, and other mutual things that we would like to share with other templates. This file would look like this:

As you can see we have added Vue.js to our project by just adding its CDN and we can freely use in the templates that extend home.html template.

And then the code inside the author.html template would look like this:

8. We also need to create a new file inside django_formset_vuejs app called urls.py. The code in urls.py should look like this:

And now we need to include django_formset_vuejs application’s URLs to our main urls.py projects file.

9.At this point, we have finished with implementing our application using Django’s nested formsets and we can start our local web server.

(env) ~/django_vuejs_tutorial$ python manage.py runserver

Conclusion

I hope that you enjoyed it, and that you can use this sample as a guide to integrate Django formsets with Vue.js.

--

--