Настройка API Django Rest Framework с JSONApi и базой данных Postgres

Сегодня часто можно увидеть веб-приложения, которые состоят из внешнего интерфейса (обычно написанного на Javascript) и внутреннего приложения, написанного на каком-либо серверном языке (Java, Python, Javascript, Ruby и т.д.). Часто клиентское приложение запрашивает данные у этого серверного приложения с помощью вызовов RESTful. Это стало настолько распространенным явлением, что многие фреймворки внедрили библиотеки, которые делают настройку такого типа серверных приложений менее болезненной, чем установка с нуля.

Давайте настроим RestAPI, используя Django Rest Framework и Django.

Вещи, используемые в этом уроке:

  • Python (настройка конкретной версии с помощью pyenv)
  • Django (вместе с Django Rest Framework)
  • JSONApi (для структурирования ответов)
  • База данных Postgres (используя docker-compose локально)

Давайте начнем

Для этого урока вам понадобится Python v 3.6.8. На большинстве систем уже установлен Python, но обычно вы найдете версию 2.7.

Существует несколько разных способов установки разных версий python, но мой любимый - использовать pyenv.

Установка pyenv

Клонируйте репозиторий pyenv в каталог, где вы хотите разместить его на своей машине (здесь я использую ~/.pyenv)

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

Определить переменную среды PYENV_ROOT

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile

Добавьте pyenv init в вашу оболочку, чтобы включить прокладки и автозаполнение

$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile

Перезапустите вашу оболочку, чтобы изменения пути вступили в силу.

$ exec "$SHELL"

Теперь у вас должна быть команда pyenv, доступная вам в терминале, однако вам необходимо убедиться, что вы установили зависимости сборки python, прежде чем пытаться установить новую версию python. Это может варьироваться в зависимости от окружающей среды. Я завершаю эти шаги для среды Mac. Однако, если вы работаете в Linux или Windows, вы можете обратиться к этой странице https://github.com/pyenv/pyenv/wiki для получения дальнейших инструкций

Если вы этого не сделали, установите инструменты командной строки Xcode (xcode-select --install) и Homebrew. Затем:

brew install openssl readline sqlite3 xz zlib

Теперь давайте установим python 3.6.8

$ pyenv virtualenv 3.6.8 myvenv

Теперь, если вы наберете версии pyenv, вы увидите список 3.6.8. Перейдите в каталог, где вы планируете создать приложение django. Теперь установите локальную версию для Python, используя pyenv. Это гарантирует, что этот проект всегда использует версию 3.6.8, но это не повлияет на глобальную версию Python.

$ cd /path/where/you/plan/to/create/django/project
$ pyenv local 3.6.8

Теперь у вас должна быть версия 3.6.8 в качестве версии по умолчанию для этого каталога.

Создание проекта Django

Обычной практикой является создание виртуальной среды для проектов Python. Это гарантирует, что зависимости для конкретного проекта распространяются только на этот конкретный проект. По сути, он создает «песочницу» для этого проекта, чтобы помочь с коллизиями версий, которые могут возникнуть при использовании глобальной области видимости для нескольких проектов.

Давайте установим virtualenv

$ pip install virtualenv

Теперь создайте новую виртуальную среду

$ virtualenv .venv

После этого вам нужно будет активировать эту виртуальную среду

$ source ./.venv/bin/activate

Теперь вы должны увидеть префикс (.venv) в командной строке терминала, указывающий, что виртуальная среда активна. Теперь давайте установим django и djangorestframework

pip install django
pip install django-filter
pip install djangorestframework

Теперь мы можем создать новый проект. Я видел разные соглашения об именах, но я склонен называть основной проект «приложением»

$ django-admin startproject app .

Теперь давайте создадим новый модуль в проекте

$ django-admin startapp posts

This will create a structure like this:

|____migrations
| |______init__.py
|____models.py
|______init__.py
|____apps.py
|____admin.py
|____tests.py
|____views.py

На корневом уровне проекта запустите:

$ pip freeze > requirements.txt

Это может быть использовано для простой установки зависимостей в будущем.

Нам также нужно добавить rest_framework и приложение posts в раздел instaled_apps файла settings.py

Вы можете запустить приложение, выполнив следующую команду в терминале

$ python manage.py runserver 0.0.0.0:8100

Настройте контейнер Postgres с помощью Docker

Docker - это инструмент, который использует контейнеры, чтобы позволить разработчику упаковывать приложение со всеми необходимыми ему частями, такими как библиотеки и другие зависимости, и отправлять все это как один пакет.

Мы будем создавать контейнер postgres, из которого наше приложение django будет читать и писать.

Во-первых, вам нужно убедиться, что вы установили docker и docker-compose перед началом работы. Если вам нужна помощь, чтобы установить эти, вы можете проверить эти ссылки https://docs.docker.com/ и https://docs.docker.com/compose/install/

После того, как вы установили их, создайте файл с именем docker-compose.yml в корневом каталоге вашего проекта и добавьте это содержимое в файл.

version: '2'
services:
  db:
    image: postgres:9.5
    environment:
      - POSTGRES_USER:db_user
      - POSTGRES_PASSWORD:password
      - POSTGRES_DB:posts
    ports:
      - "5432:5432"
    volumes:
      - ./docker/postgresql/data:/var/lib/postgresql/data

После сохранения этих изменений в файле docker-compose.yml вы можете запустить этот файл и запустить его из корневого каталога проекта:

$ docker-compose up

Это запустит контейнер базы данных postgres. В docker-compose.yml вы:

  • настроили пользователя, пароля и имени базы данных
  • переадресовали порт 5432, так что один и тот же порт отображается на хост и контейнер
  • и настроили том так, чтобы данные, которые вы сохраняете в базе данных, сохранялись там навсегда
  • * Одна заметка, если вы используете Mac, вам нужно будет использовать приложение Docker, чтобы дать разрешения для Docker иметь возможность монтировать том в вашей файловой системе. Иначе это даст ошибку разрешений

Нам нужно создать базу данных, пользователя и роль в postgres внутри контейнера Docker. Для этого вам необходимо определить название вашего контейнера. Внутри каталога верхнего уровня вашего проекта (где находится ваш файл docker-compose.yml) введите:

$ docker-compose ps

Это должно показать что-то вроде этого:

В этом случае «python-django_db_1» будет именем контейнера

Теперь мы будем запускать команды внутри контейнера докера с нашего хоста

$ docker exec -it YOUR_CONTAINER_NAME psql -U postgres -c "CREATE DATABASE YOUR_DB_NAME;"
$ docker exec -it YOUR_CONTAINER_NAME psql -U postgres -c "CREATE USER YOUR_USER_NAME SUPERUSER PASSWORD 'YOUR_PASSWORD';"
$ docker exec -it YOUR_CONTAINER_NAME psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE YOUR_DB_NAME TO YOUR_USER_NAME;"

Вам нужно заменить YOUR_CONTAINER_NAME, YOUR_DB_NAME, YOUR_USER_NAME, YOUR_PASSWORD на правильные значения для вашего проекта.

Теперь вам нужно подключить ваше приложение django к базе данных postgres.

Подключение приложения Django к базе данных Postgres

Вам нужно будет установить пакет psycopg2.

Однако для сборки psycopg2 вам потребуется pg_config. Не устанавливая полный postgres на свой локальный компьютер, вы можете запустить:

brew install libpq

После этого вам нужно будет обновить переменную PATH в bash_profile

$ echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> ~/.bash_profile

(Возможно, вам потребуется открыть новое окно терминала, чтобы ваши изменения в .bash_profile вступили в силу)

Теперь вы сможете успешно установить psycopg2

$ pip install psycopg2

Замените конфигурацию базы данных по умолчанию в файлах YOUR_PROJECT_NAME/app/settings.py на:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'posts',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': ''                 # установить пустую строку по умолчанию
    }
}

Убедитесь, что вы можете запустить API-интерфейс Django, и он успешно работает. Запустите python manage.py runserver 0.0.0.0:8100, и вы должны увидеть что-то похожее на:

Теперь, когда база данных настроена и подключена к приложению django, нам нужно перенести базу данных, чтобы инициализировать все специфичные для django таблицы в базе данных. Запустите:

$ python manage.py migrate

Если миграция прошла правильно, у вас должна быть настроена база данных и она готова к работе.

Напоследок давайте создадим суперпользователя в базе данных

$ python manage.py createsuperuser

Следуйте инструкциям в терминале, чтобы добавить имя пользователя, адрес электронной почты и пароль. Теперь у вас должен быть пользователь администратора, созданный в вашей базе данных.

Установка и настройка djangorestframework-jsonapi

JSON:API - это спецификация для построения API. Он обычно используется с такими интерфейсами, как Emberjs. Djangorestframework-jsonapi упрощает сериализацию ваших данных в структуру json:api.

$ pip install djangorestframework-jsonapi

Не забудьте запустить pip freeze, чтобы обновить ваши требования. Txt:

$ pip freeze > requirements.txt

Вам нужно будет добавить блок кода в файл YOUR_PROJECT_DIR/app/settings.py

REST_FRAMEWORK = {
    'PAGE_SIZE': 10,
    'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
    'DEFAULT_PAGINATION_CLASS':
        'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework_json_api.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework_json_api.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework_json_api.filters.QueryParameterValidationFilter',
        'rest_framework_json_api.filters.OrderingFilter',
        'rest_framework_json_api.django_filters.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
    ),
    'SEARCH_PARAM': 'filter[search]',
    'TEST_REQUEST_RENDERER_CLASSES': (
        'rest_framework_json_api.renderers.JSONRenderer',
    ),
    'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json'
}

Настройка приложения posts

Давайте добавим модель Post в приложение posts.

В файле posts/models.py добавьте это:

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()


class Post(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)

Далее нам нужно создать сериализатор для этой модели. Создайте файл в каталоге приложения posts с именем serializers.py и добавьте этот код в этот файл:

from rest_framework_json_api import serializers

from .models import Post


class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        fields = '__all__'

Далее нам нужно создать представление. Добавьте этот код в файл posts/views.py:

from rest_framework import viewsets

from .models import Post
from .serializers import PostSerializer


class BaseViewSet(viewsets.ModelViewSet):
    def get_queryset(self):
        return self.model.objects.all()


class PostViewset(BaseViewSet):
    serializer_class = PostSerializer
    model = Post

Далее нам нужно создать файл urls.py в папке posts. Создайте этот файл и добавьте этот код:

from django.conf.urls import include, url
from rest_framework import routers

from .views import PostViewset

api_router = routers.SimpleRouter()
api_router.register(r'posts', PostViewset, base_name='post')

urlpatterns = [
    url(r'', include(api_router.urls))
]

Далее, поскольку мы создали новую модель, нам нужно будет перенести их в базу данных. Запустите эти две команды:

python manage.py makemigrations
python manage.py migrate

На данный момент вы можете запустить приложение и посетить localhost:8100/api/posts/

python manage.py runserver 0.0.0.0:8100

Вы должны увидеть что-то вроде:

Вы можете использовать форму внизу этой страницы для публикации данных и создания записи

После этого вы должны увидеть что-то вроде этого в теле полезной нагрузки:

На данный момент вы настроили api django rest framework, который работает локально с базой данных postgres, работающей в контейнере Docker, который возвращает структурированные полезные нагрузки json:api!

https://medium.com/@johnking_75842/django-rest-framework-api-setup-w-jsonapi-and-postgres-database-2cd11038b43b

Вернуться на верх