Django Cheatsheet
I’ve always wanted to experiment with Django after trying out Flask a few years ago. After some initial experimentation to build a search tool for solar farms (django backend, react frontend), I think Django is an optimal choice for building an API quickly from data models. It works great with PostgreSQL and database-driven applications.
Below is a cheatsheet I compiled while building out my experimental app — hope it’s helpful, and let me know what’s missing!
Background
Django is a python-based web framework that follows a Model-View-Template pattern, where:
- Model is the interface to your data. Logical structure behind the application and represented by a DB
- View is the user interface. Whatever your browser renders via HTML/CSS/JS
- Template is the file that defines the structure or layout of the user interface
Generally, Django is known to be fast, secure, scalable and comes with “batteries included” (user authentication, content management, etc). It is used by newspaper publishers like Washington Post, The Onion, NYT, and apps such as Firefox, ClubHouse, Instagram, Pinterest, Eventbrite, Doordash, and Robinhood.
The Django REST Framework makes it very easy to build CRUD APIs. It makes serialization easier as it follows Django’s class-based views. Overall, a great toolkit for building RESTful APIs.
Cheatsheet & Snippets
Setup & Installation
create a virtual environment
python3 -m venv <name>
activate the venv
source venv/bin/activate
Install django
pip install django
Create a project
django-admin startproject <name> .
Create an app in the project
django-admin startapp <name>
Remember to add the app to the settings.py file under INSTALLED_APPS
after you create it
Run the server, migrations, etc
Start the server
python3 manage.py runserver
Create a migration
python3 manage.py makemigrations
Run a migration
python3 manage.py migrate
Note: Always run makemigrations
followed by migrate
after making modifications to data models
Django admin
The admin console is good for inspecting data, users, apis, etc. Usually at localhost:8000/admin
Need to create a login for the admin console:
python3 manage.py createsuperuser
You can customize the admin console by updating the admin.py
file
Data Models
When you create new models:
- define models in models.py
- update the serializer in serializers.py
- register them in admin.py. The admin.py file must be updated for new models to show up in the admin console.
An example of one-to-many relationships: A book with many characters
The “child” such as characters in a book, should reference the parent via foreign key:
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='characters')
When you import models from the same directory, you may have to do from .models import ...
rather than from models import ...
See here for field options for data models.
Django REST Framework (DRF)
Installation:
pip install djangorestframework
Add rest_framework
to the INSTALLED_APPS
list in settings.py
To obtain an auth token, hit http://localhost:8000/auth/
(POST) with username and password parameters for a given user. To set up permissions, add this to settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
Add this to the view set in views.py: authentication_classes = (TokenAuthentication, )
This way, only people with an auth token can see the data.
Registering DRF Views as Endpoints
There are multiple types of views in DRF. The most widely used ones are:
- Class-based views that extends
APIView
class ModelViewSet
- Generic
View
s which map closely to DB models, built on top of APIViews
More on DRF Views here
ModelViewSet
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
APIView
Typically handles GET
, POST
based on the incoming query. For example, to create an Authors
view based on the Books
table:
class Authors(APIView):
renderer_classes = [JSONRenderer]
# return all the unique authors of books
def get(self, request):
authors = Books.objects.order_by().values('author').distinct()
return Response(states)
In api/urls.py
, the two Views are registered differently. One through the router, another by the path (because you can’t add generic Views in routers)
from django.urls import path, include
from rest_framework import routers
from .views import BookViewSet, Authors
router = routers.DefaultRouter()
# ModelViewSet
router.register('books', BookViewSet)
urlpatterns = [
path('', include(router.urls))
# APIView
path('authors/', Authors.as_view(), name="authors")
]
CORS
Required to allow a frontend application to query API in django
- install django-cors-headers: https://github.com/adamchainz/django-cors-headers
- update settings.py
INSTALLED_APPS
and add it toMIDDLEWARE
- also add
CORS_ALLOWED_ORIGINS
in settings.py, which needs to include the frontend app address in addition to localhost
Database
The default is sqlite. To change to Postgres:
To run this locally, make sure you have postgres installed on your machine, and create a database for your project. Install psycopg2 withpip install psycopg2
Fill in your own database credentials in a .env file (example using django Environ)
Finally, update settings.py
:
import environ
env = environ.Env()
environ.Env.read_env()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': env("DB_NAME"),
'USER': env("DB_USER"),
'PASSWORD': env("DB_PASSWORD"),
'HOST': env("DB_HOST"),
'PORT': env("DB_PORT")
}}
More detailed instructions on using postgres with django
Of course, remember that your local .env file should not be pushed to production. To point your app to a production DB, just update the environment variables.
Remember to recreate any users with the createuser or createsuperuser command
Productionizing with Heroku
- install
pip install python-decouple
- create a
.env
file and move SECRET_KEY from settings.py over - Install
pip install dj-database-url
and update DB path in settings.py - Install
pip install dj-static
, update wsgi.py to useCling
from dj_static import Cling from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<project>.settings") application = Cling(get_wsgi_application())
5. Run pip freeze > requirements-dev.txt
6. create requirements.txt
for heroku, which includes requirements-dev.txt and others
-r requirements-dev.txt
gunicorn
psycopg2
7. create a Procfile
web: gunicorn <project>.wsgi --log-file -
8. create runtime.txt
and input the latest python version supported by heroku
9. deploy with Heroku after pushing changes, either from the dashboard, cli, or automatic github integration
10. monitor logs with heroku logs --tail -a <project>
Running one-off scripts
Install django-extensions and userunscript
python3 manage.py runscript <script.py>
Example workflow to build a REST API with Django
- Create a directory for the project
- start python venv
- install django, djangorestframework
- start django project
- django-admin startproject for the project
- django-admin startapp for the app
- start the server with
python3 manage.py runserver
- Run migrations with python manage.py migrate
- update urls.py (if applicable, create a new one for your new app in step 6)
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include('api.urls')),
]
10. update settings.py to include rest_framework and api (new project) in INSTALLED_APPS
11. create superuser with python3 [manage.py](<http://manage.py>) createsuperuser
12. routing: in urls.py of your app, do from rest_framework import routers
13. define data models in models.py
14. run python3 manage.py makemigrations
and migrate
. If you run into issues like changes not being detected, run python3 makemigrations <app name>
15. Set up serializers for data models in serializers.py
16. Create views using the serializers (views.py)
17. Register the viewsets in your router (urls.py)
18. Add custom API methods. For example, define POST calls in views.py