3. Web api - Django

3.1. Creation of virtual env

python -m venv venv
source venv/bin/activate

3.2. Instalation

pip install django
pip install djangorestframework # remember to add 'rest_framework', to settings.py - INSTALLED_APPS
pip install django-extensions # remember to add 'django_extensions', to settings.py - INSTALLED_APPS
pip install markdown       # Markdown support for the browsable API.
pip install django-filter  # Filtering support - remember to add to settings.py 'django_filters' - INSTALLED_APPS

3.3. Creation of dependencies

pip freeze > requirements.txt

3.4. Creation of new project

django-admin startproject servermonitoring
cd servermonitoring
python manage.py migrate
python manage.py runserver

3.5. Create of new app

django-admin startapp api

3.6. Check in browser

  • Chrome/Postman address http://127.0.0.1:8000/

  • Curl http://127.0.0.1:8000/

3.7. Adjust settings

Tip

look on manage.py ex. using command: cat manage.py there you got way how django is launched

change setup in settings.py

vim servermonitoring/settings.py

Hint

you can do that using vim vim servermonitoring/settings.py

Or directly in pyCharm

# servermonitoring/settings.py

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django_filters',
 'django_extensions',
 'rest_framework',
 'api'
]

3.8. Tests creation

# api/tests.py

from django.test import TestCase
from rest_framework import status

from api.models import Server

class ServerModelTestCase(TestCase):
    """Server model tests"""

    def setUp(self):
        """Definition of startup values"""

        self.server = Server(address='127.0.0.1')

    def test_model_repr(self):
        self.assertEqual("<Server address: 127.0.0.1>", repr(self.server))

    def test_model_str(self):
        self.assertEqual("Server o adresie: 127.0.0.1", str(self.server))

3.9. Test execution

python manage.py test

3.10. Model creation

from django.db import models

class Server(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    location = models.CharField(max_length=100, null=True, blank=True, default='')
    available = models.BooleanField(default=False)
    address = models.GenericIPAddressField()
    admin_contact = models.EmailField(max_length=70, null=True, blank=True)
    admin_phone = models.CharField(max_length=70, null=True, blank=True, default='')

    def __repr__(self):
        return "<{} address: {}>".format(self.__class__.__name__, self.address)

    def __str__(self):
        return "{} o adresie: {}".format(self.__class__.__name__, self.address)

3.11. Creation and execution of migations

python manage.py makemigrations
python manage.py migrate

3.12. Checking of sql migrations code

python manage.py sqlmigrate api 0001

3.13. Execution of test after migrations

python manage.py test

3.14. Addint view test

# api/tests.py
# ............

from django.test import TestCase
from rest_framework import status
from api.models import Server
from django.urls import reverse

class ViewServerTestCase(TestCase):
    """Test for server view"""

    def test_create_server(self):
        """We check if we can create server (post)"""

        url = reverse('servers')
        data = {"location": "office", "address": "127.0.0.1"}

        response = self.client.post(url, data, format="json")

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(len(response.data), 1)

    def test_view_server_list(self):
        """We check if we get proper amount of servers"""

        url = reverse('servers')

        response = self.client.get(url, format="json")
        self.assertEqual(response.status_code, status.HTTP_200_OK)

3.15. Serializer

# api/serializers.py

from rest_framework import serializers

from .models import Server

class ServerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Server
        fields = '__all__' # albo fields = ('location', 'address',)

3.16. Adding view

# api/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .serializers import ServerSerializer
from .models import Server

class ServerList(APIView):
    """Lista serwerow"""

    serializer_class = ServerSerializer

    def get_queryset(self):
        queryset = Server.objects.all()
        location = self.request.query_params.get('location', None)

        if location is not None:
            queryset = queryset.filter(location__icontains=location)
        return queryset

    def get(self, request, format=None):

        servers = self.get_queryset()
        serializer = ServerSerializer(servers, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ServerSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

3.17. Add urls

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

from api import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('servers/', views.ServerList.as_view(), name='servers')
]

3.18. Methods

  • Get

  • Post

  • Put

  • Delete

3.19. HTTP codes

  • 200 - success. Request correct. Response correct.

  • 400 - fail request. Bad request / problems with authentication.

  • 403 - access denied,

  • 404 - no such page,

  • 500 - internal error. Usually because of developer made mistake.

3.20. Requests

3.21. Responses

3.22. Settings

3.23. View

3.24. Migations

Hint

To see migrations we can execute python manage.py showmigrations

3.25. Orm

3.26. Django extensions

python manage.py show_urls
python manage.py shell_plus # better console/dev server- ipython
python manage.py runserver_plus # server

3.27. Practice

3.27.1. Zero

  • Napraw test,

  • Dodaj do testu sprawdzanie daty - stworzenia wpisu

3.27.2. First

  • Create 4 hosts - each in different way

    • Using web page,

    • Using request from postman,

  • Create model, which:

    • Would be storing date

3.27.3. Second

  • Stwórz endpoint (POST), który:

    • Będzie

3.27.4. Third