Setting up a Basic Django Backend

Alexis Chilinski
The Startup
Published in
8 min readJul 27, 2020

One of my friends recently called me a “Django-whisperer.” Having wanted to learn Python since I began my software engineering journey, I am honored to have been given this title.

To help future Django-whisperers, this blog post will be a short tutorial for setting up a basic Django backend. The goal of the app will be to add a review to a website (like Yelp). Therefore we will need a Review model that has a “name” field, a “review” field, and a “date created” field.

First, make sure you have Python and pip installed on your machine. Python3 and pip3 are the most recent versions, and that’s what I use. So create a project folder, and then inside the folder, you need to create a virtual environment (see my post about the importance of virtual environments here). Python has a built-in mechanism for creating a virtual environment, so just run this command inside your project directory:

python3 -m venv venv

where the second venv is the name you want to give your virtual environment. So if I were to name my venv “cool_venv,” the command would be. python3 -m venv cool_venv. Once that’s complete, you want to activate the venv by running:

. ./venv/bin/activate

and you replace venv with the name of your virtual environment. So my command would be . ./cool_venv/bin/activate. If it activated correctly, you should see an indicator in your command line. Now we can start installing necessary packages (Django, Django Rest Framework, Cors, etc). So you can run:

pip3 install django djangorestframework django-cors-headers

To make sure they installed correctly, you can run pip freeze to see the list of packages and their versions. Now you can start your Django project! Run this command:

django-admin startproject 'project_name'

where ‘project_name’ is what you want to name your project (omit the quotation marks). Then CD into that directory, you should see a manage.py file. Wherever you see a manage.py is the root directory, and that’s where you will run all of your main commands (runserver, migrate, etc). From this root directory, open the project in your favorite text editor (in your text editor, make sure you’re using the Python interpreter within the venv). Run this command to create your app directory (for models, views, serializers, etc):

python3 manage.py startapp 'app_name'

where ‘app_name’ is replaced by what you want to name your app (omit the quotation marks). Keep in mind, a project can contain many apps, so pick a name based on what you want the main function of this app to be. For example, if the primary function of this app is to write reviews, then maybe name it ‘reviews.’

You should see two folders in this directory (one is the project name, one is the app name) in addition to the manage.py file. Open your project folder and go into the settings.py file to add the following to your “INSTALLED APPS” list:

INSTALLED_APPS: [
...
"rest_framework",
"corsheaders",
"app_name",
...
]

There are other items you need for cors (whitelist, allow-origin, etc). See the link here to figure out which would work best for you, but for now we can just add:

CORS_ORIGIN_ALLOW_ALL = True

but keep in mind this is not secure. You will also need to add special middleware for cors:

MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]

The site instructs to give them a specific place, so see the docs for more information.

BONUS: Be aware, your settings.py file also contains a SECRET KEY. Keeping it in this file is not secure, and you should store it in a .env file and then include that in your .gitignore file. You can access variables from your .env file by installing the python-decouple package. Once installed with pip install python-decouple, you can import it into settings as:

from decouple import config

and then you can retrieve the secret key with this code:

SECRET_KEY = config('SECRET_KEY')

where ‘SECRET_KEY’ is whatever you gave it in the .env file.

Now let’s migrate and run the server. Run these commands (and again, make sure you’re running these commands in the root directory that has the manage.py file):

python3 manage.py migratepython3 manage.py runserver

Assuming everything worked correctly, you should be able to go to localhost:8000 (unless you designate another port) and you should see this page:

Awesome! So one of the best parts about Django is the superuser. This allows you to log in as an admin and manage the data in your database. To set this up, run this command:

python3 manage.py createsuperuser

Follow the prompts, and once it’s complete, you can now navigate to localhost:8000/admin and you can login with those credentials and you will see this page:

Django admin page at localhost:8000/admin once logged in as superuser

Now for the good, classic API stuff. Open your app folder and go into your models.py. Like I mentioned before, our Reviews will have a name (string datatype), a review field (string datatype), and a date_created field (date datatype). So it will look like this:

class Review(models.Model):
name = models.CharField(max_length=20)
review = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)

CharField requires a max_length. Check the docs to see any other field rules, and for a list of field types. Keep in mind, I used ‘TextField’ for reviews because it doesn’t have a max amount of characters, unlike CharField.

Once this is complete, time to make a migration! Run these simple commands:

python3 manage.py makemigrationspython3 manage.py migrate

BONUS: If you make any mistake and you need to rollback to a previous migration, you can run this command:

python3 manage.py migrate 'app_name' migration_file_name

where the file name is usually preceded by a number (e.g. 0001_). You don’t need to file extension type, just the name. And of course, replace ‘app_name’ with the name of your app (omit the quotation marks). Once this is successfully rolled back, you can delete the unwanted migrations.

Next we will create a serializers file. In your app directory (where the models.py file is), add a serializers.py file and open it. You will need to import the serializers feature from the rest_framework package as well as the Review model at the top of this file:

from rest_framework import serializers
from .models import Review

This is just a simple Review API, so we want to be able to view all the fields when looking at an instance of a review (like in JSON format, for example). The Review Serializer will look like this:

class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = '__all__'

Obviously if you need more customization (only see specific fields, serializer depth, etc) then you can reference the rest framework docs.

How the data will look based on our serializer code

Now we move onto what you can actually do with this model, meaning what HTTP requests you can make. This will be specified in our views.py file. First, you will need to import as follows:

from django.shortcuts import render
from rest_framework import viewsets, permissions
from .serializers import ReviewSerializer
from .models import Review

And then we can create a viewset! There are a lot of different ways to set up a viewset depending on what specifically you need and if you need permissions or extra actions, but we will stick with the simpler Model viewset:

class ReviewViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.AllowAny]
queryset = Review.objects.all()
serializer_class = ReviewSerializer

This means that you can sent any HTTP request on this model (GET, POST, PUT, PATCH, DELETE) and anyone can do so (see permissions). The queryset is what the view is based on (this will return all the Review instances/objects). And lastly, it will set them up with the designated serializer.

Now we need a way to view this model! This requires an endpoint. So in your app folder, create a urls.py file and open it. You will need to import as follows:

from rest_framework import routers
from .views import ReviewViewSet

and then to “register” an endpoint, write out this code:

router = routers.DefaultRouter()router.register('reviews', ReviewViewSet, 'reviews')urlpatterns = router.urls

Your main urls.py file (in your project directory) will be looking for that “urlpatterns” so make sure you include it. The first ‘reviews’ will be in the actual url, the second ‘reviews’ is whatever you want to call your endpoint.

Then open up the urls.py file found in your project directory (the directory that has the settings.py file). In here, you should already have an admin url (otherwise you’re localhost:8000/admin wouldn’t have worked). In the importing part, from django.urls you will need to also import include, so your imports will look like this:

from django.contrib import admin
from django.urls import path, include

Then you can set up another root:

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app_name.urls')),
]

I usually like to leave an empty string, which means the endpoints will be built off of the root localhost:8000/ . Replace ‘app_name’ with the name of your app folder. As long as this is setup properly, when you run your server, you should be able to navigate to localhost:8000/reviews, which will of course show an empty page since we haven’t created any reviews yet. You of course can test this in Postman or Insomnia or whichever app you prefer to use.

Endpoint for all reviews, you can send GET and POST requests here
Use a review’s id in the endpoint to gain access to PATCH and DELETE requests

And of course, as a finishing touch, don’t forget to register it on the admin site. In your admin.py file within your app directory, import as follows:

from django.contrib import admin
from .models import Review

and register the model like this:

admin.site.register(Review)

Once this is saved, you should be able to navigate to localhost:8000/admin and it will now look like this:

And now you can see the Reviews section! Once you click on it, it will show you all the reviews objects and you can edit/add/delete as admin.

Once again, this is a very basic Django backend, but I hope it helps someone dive into the world of Django APIs.

For further reading, feel free to check out a couple of my other Django-based blogposts:

Seeding a Django database

Extending the User Model

Here’s the link to my github repo with all of this working code: https://github.com/alexiscait142/basic_django_backend

Happy Django-ing!

--

--