Skip to content

Instantly share code, notes, and snippets.

@luigiMinardi
Last active May 14, 2024 08:30
Show Gist options
  • Save luigiMinardi/52868c1e6f11d7a67c5b0e4ec63d6789 to your computer and use it in GitHub Desktop.
Save luigiMinardi/52868c1e6f11d7a67c5b0e4ec63d6789 to your computer and use it in GitHub Desktop.
How to start a REST API with Django and DRF

How to start a REST API with Django and DRF

In this gist you will learn the basic to create a simple REST API with Django and Django REST Framework with a basic crud.

Create venv

python3 -m venv .venv

Activate venv

mac/linux

source .venv/bin/activate

windows

.venv\Scripts\activate.bat

Install dependencies

pip install django djangorestframework
django-admin startproject setup .

*When I say app_name is your app name, so put the name you want, in snake_case.

python manage.py startapp app_name

Go to setup > settings.py, then on the INSTALED_APPS section add:

'rest_framework',
'app_name',

Run server

python manage.py runserver

If you want to change the port later just put the port you want, in this exemple below I'm running on port 3000.

python manage.py runserver 3000

Create your models classes

Go to app_name > models > classname.py and put you models there.

In the default django project (executed before right after the dependences instalation) you'll have a models.py file that you do can use to put all your models, but it will be a mess as your project get bigger, so create the models folder and delete the models.py file.

If you do that be sure to add the __init__.py in the models folder and also do this:

from .classname import ClassName

.classname is your classname.py file and ClassName is your class name. You'll need to do it on __init__.py for every new class of yours in the models folder, that way you will be able to import it properly in other places of your code.

*I don't know if the classname.py should be lowercase or snake_case, so use lowercase, if the readability is very poor go with snake_case.

The class will have a name in singular and with PascalCase ClassName, that you can change for the name you want.

from django.db import models

class ClassName(models.Model):
    # ...
    pass # For beginners that dont know this will allow the class to not bug your code even being empty, remove it if you copy-paste this code that is just a python feature to examples

To create your model look at Django Models Documentation, and to know which fields you can use check the Django Fields Documentation.

Then run your migrations.

python manage.py makemigrations
python manage.py migrate

Create your admins classes

Go to app_name > admin.py.

Here you will use the same ClassName from the models but with it name in plural.

from django.contrib import admin

from app_name.models import ClassName

class ClassNames(admin.ModelAdmin):
    # ...
    pass

admin.site.register(ClassName, ClassNames)

Then run this command in your terminal to create your super user.

python manage.py createsuperuser

Go to http://127.0.0.1:8000/admin/ (or the port you choosed before), and try to login to check if you superuser was created correctly.

Create your serializers classes

Go to app_name > serializer.py.

Here is the same ClassName from modules + Serializer and in singular.

from rest_framework import serializers

from app_name.models import ClassName

class ClassNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClassName
        fields = '__all__'
        """
            The serializer is a filter of the data 
            that you want to show in you API,
            if you want to show just some specific data
            change the "fields = '__all__'" to: 
        """
        fields = ['data_1',  ... , 'data_N']

Remember that those datas are fields of your DB (at least in that case, I don't know if have any that isn't that way).

Create your viewsets

Go to app_name > views.py.

Here is the same ClassName from modules and in plural, but the ViewSet part is in singular.

from rest_framework import viewsets

from app_name.models import ClassName
from app_name.serializer import ClassNameSerializer

class ClassNamesViewSet(viewsets.ModelViewSet):
	"""What the ViewSet Shows"""
	queryset = ClassName.objects.all()
	serializer_class = ClassNameSerializer

Create your urls

Go to setup > urls.py.

On router.register, the names are in plural and the same as your ClassName model. The first argument will be lowercase and the basename a PascalCase.

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

from app_name.views import ClassNamesViewSet

router = routers.DefaultRouter()
router.register('classnames', ClassNamesViewSet, basename='ClassNames')

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

The first argument of the router.register is the url path, so when I define as classnames I'll acess it trought http://127.0.0.1:8000/classnames. You can change it if you want.

Also a good to remember is that to put params in a route it need to be at the end of the urlpatterns (after all the non params routes). The param is specified as <type:name>, eg. <int:pk>.

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls))
     path('classnames/<int:pk>/do-something/', YourViewClass.as_view())
]

Improve it

Well, now is all up to you. the CRUD is completed, you can check your api at http://127.0.0.1:8000/, if you access trought the browser you'll be able to use the UI from django to do the CRUD and test everything. You can also do it from Insomnia or Postman. Tough the best for you is to do automated tests of your API. I'll do a gist about it soon so check it out when it get completed :)

A very important read for you now is the Classy Django REST Framework.

To improve your API you'll have all the Django Docs and the Django REST Framework Docs to help you.

*The Django docs URLs is going to the Django 5.0, the DRF Docs are at the 3.14 and the CDRF at DRF 3.14, in case you're in the future take it as a warning, maybe this tutorial is outdated and don't work anymore. If it does work make sure that you're in your django version documentation, since using things of an outdated documentation can generate bugs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment