Настройка 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
Вернуться на верх