Share This
Связаться со мной
Крути в низ
Categories
//Создаём веб-приложение с бэкендом на Django и фронтендом на React

Создаём веб-приложение с бэкендом на Django и фронтендом на React

20.09.2020Category : Python

Перевод статьи «Tutorial: Django REST with React (Django 3 and a sprinkle of testing)»

В этом материале вы узнаете:

  • как создать простое REST API на Django;
  • как добавить React в проект Django;
  • как соединить Django и React.

Подготовка

Вам понадобятся:

  • базовое понимание Python и Django;
  • базовое понимание JavaScript (и спецификации ECMAScript 2015) и React;
  • установленный Node.js.

Создаём проект Django в виртуальном окружении Python

Создайте новую папку и перейдите в неё:

mkdir django-react && cd $_

Потом активируйте виртуальное окружение Python:

python3 -m venv venv source venv/bin/activate

Примечание все следующие команды нужно выполнять из папки django-react и с активированным виртуальным окружением.

Установите зависимости Django и Django REST Framework:

pip install django djangorestframework

После установки создайте новый проект Django:

django-admin startproject django_react

Теперь сделаем простое API на Django для создания и хранения контактов.

Создаём приложение на Django

В каждом проекте Django может быть много приложений. Приложения можно делать переиспользуемыми: такими, что их можно добавить в менеджер пакетов Python и установить через него в другой проект, в котором нужно такое приложение.

Виртуальный класс Школы программистов для учеников 3–11 классов

Старт 5 октября, 8 месяцев, Онлайн, От 71 200 до 76 000 ₽

tproger.ru События и курсы на tproger.ru

Для создания нового приложения Django используется команда:

django-admin startapp app_name

где app_name — название приложения.

В нашем случае команда будет выглядеть так:

django-admin startapp leads

Она создаст приложение leads в папке django-react. Теперь структура папок в проекте должна выглядеть так:

(venv) your@prompt:~/Code/django-react$ tree -d -L 1 . ├── django_react ├── leads └── venv

Теперь сделаем так, чтобы Django проект использовал новое приложение. Откройте файл django_react/settings.py и добавьте приложение в INSTALLED_APPS:

INSTALLED_APPS = [     'django.contrib.admin',     'django.contrib.auth',     'django.contrib.contenttypes',     'django.contrib.sessions',     'django.contrib.messages',     'django.contrib.staticfiles',     'leads.apps.LeadsConfig', # activate the new app ]

Создаём модель в базе данных с помощью Django

Модель — это объект, представляющий собой данные из таблицы. Почти каждый веб-фреймворк использует модели, и Django — не исключение.

Модель Django может иметь одно или больше полей. Каждое поле соответствует полю в таблице.

Мы собираемся хранить контакты, поэтому модель Lead может состоять из этих полей:

  • имя;
  • email;
  • сообщение.

(Можно добавлять и другие поля, например телефон). Добавим ещё поле с временем создания модели, потому что по умолчанию Django этого не делает.

Откроем leads/models.py и опишем модель Lead:

from django.db import models  class Lead(models.Model):     name = models.CharField(max_length=100)     email = models.EmailField()     message = models.CharField(max_length=300)     created_at = models.DateTimeField(auto_now_add=True)

Примечание изучите документацию Django о полях. Когда придумываете структуру модели, выбирайте самые подходящие для вашего случая поля.

Создадим миграции командой:

python manage.py makemigrations leads

и применим их к базе данных:

python manage.py migrate

Займёмся тестированием

Вы могли подумать «А как же тестирование?».

Мнение: разработка через тестирование — это тупо. Обсуждаем TDDtproger.ru

Существует масса туториалов по Django, начинающихся примерно так:

class SomeModelModelTest(TestCase):     def setUp(self):         SomeModel.objects.create(             name=fake.name(),             email=fake.email(),             phone=fake.phone_number(),             message=fake.text(),             source=fake.url()         )     def test_save_model(self):         saved_models = SomeModel.objects.count()         self.assertEqual(saved_models, 2)

Не надо так. Нет никакого смысла ни в тестировании стандартной модели Django, ни в тестировании Django ORM. Что точно не нужно тестировать при создании приложения на Django:

  • встроенный код Django (модели, представления);
  • встроенные функции Python.

Не тестируйте то, что уже протестировано! Так что же тогда тестировать?

Добавили свой метод в модель Django — протестируйте его. Дополнили стандартное представление — протестируйте его. Но как узнать, что именно нужно протестировать?

Узнать это поможет библиотека coverage. Установите её:

pip install coverage

Теперь после каждого добавления или изменения кода запускайте coverage:

coverage run --source='.' manage.py test

и создавайте отчёт:

coverage html

Вы увидите, что именно нужно протестировать. Если предпочитаете увидеть отчёт в командной строке, запустите команду:

coverage report

Сериализаторы Django

Сериализация — это конвертация объекта Python в другой формат. После сериализации можно сохранить объект в файл или послать его через сеть.

Как оценить профессионализм программиста за 5 вопросов — отвечают экспертыtproger.ru

Почему сериализация необходима? Модель Django — это класс Python. Чтобы превратить её в данные в формате JSON, нужна сериализация.

Сериализаторы работают и в обратном направлении: они конвертируют JSON в объекты. Это позволяет:

  • отображать модель Django в браузере с помощью конвертации в JSON;
  • делать запросы CRUD (create — read — update — delete) к API в формате JSON.

Суммируя: сериализаторы в Django можно использовать для совершения операций с моделями Django через API.

Создайте новый файл leads/serializers.py. Сериализатор LeadSerializer содержит нашу модель и поля:

from rest_framework import serializers from .models import Lead  class LeadSerializer(serializers.ModelSerializer):     class Meta:         model = Lead         fields = ('id', 'name', 'email', 'message')

Созданный дочерний класс от класса serializers.ModelSerializer. ModelSerializer в Django похож на ModelForm. Он подходит, когда нужно, чтобы сериализатор соответствовал модели.

Создаём представления

Если вы раньше работали с другими фреймворками, то можете удивиться, что в Django нет контроллеров.

Веб-фреймворки: введение для новичковtproger.ru

Контроллеры содержат логику обработки запросов и возвращения ответов. В традиционной архитектуре MVC есть модель (Model), представление (View) и контроллер (Controller). Примеры MVC фреймворков: Rails (Ruby), Phoenix (Elixir), Laravel (PHP).

Django — это фреймворк MVT. MVT — это модель, представление и шаблон (Template). В Django есть много типов представлений: функции-представления, представления, основанные на классах, и обобщённые представления.

Используйте функции-представления только если изменение обобщенных представлений займет больше, чем написание представления заново.

Мы будем использовать обобщённые представления. Наше простое приложение будет:

  • возвращать выборку моделей;
  • создавать новые объекты в базе данных.

С помощью документации можно узнать, что есть представление для возвращения выборки и создания моделей: ListCreateAPIView. Это представление содержит queryset и serializer_class.

queryset — это выборка данных, которую приложение будет возвращать. В нашем случае — все модели Lead. serializer_class — класс сериализатора для модели.

from .models import Lead from .serializers import LeadSerializer from rest_framework import generics  class LeadListCreate(generics.ListCreateAPIView):     queryset = Lead.objects.all()     serializer_class = LeadSerializer

С помощью трёх строк кода мы создали представление для обработки GET и POST запросов.

Чего ещё не хватает? Маршрутизации URL. Другими словами, нам нужно соединить URL и представления.

Настраиваем маршрутизацию url

Нам нужно сделать так, чтобы GET и POST запросы к api/lead/ обрабатывались представлением LeadListCreate, которое будет возвращать и создавать модели.

Чтобы настроить маршрутизацию URL, отредактируйте файл django_react/urls.py, добавив туда url приложения:

from django.urls import path, include  urlpatterns = [     path('', include('leads.urls')), ]

Так мы указываем Django, что нужно использовать url, которые есть в приложения leads.

Теперь создайте файл leads/urls.py. В нём мы соединим представление LeadListCreate и url api/lead/:

from django.urls import path from . import views  urlpatterns = [     path('api/lead/', views.LeadListCreate.as_view() ), ]

И наконец, включим rest_framework в INSTALLED_APPS. Откройте django_react/settings.py и добавьте приложение в INSTALLED_APPS:

# Application definition  INSTALLED_APPS = [     # omitted for brevity     'leads.apps.LeadsConfig',     'rest_framework' ]

Запустим сервер Django:

python manage.py runserver

Перейдите по url http://127.0.0.1:8000/api/lead/ и вы увидите API:

sozdajom veb prilozhenie s bekendom na django i frontendom na react 78dddb9 - Создаём веб-приложение с бэкендом на Django и фронтендом на React

Примечание в продакшене лучше отключить возможность просмотра API. Это можно сделать в конфигурации:

REST_FRAMEWORK = {     'DEFAULT_RENDERER_CLASSES': (         'rest_framework.renderers.JSONRenderer',     ) }

Соединяем Django и React

У многих разработчиков возникают вопросы по поводу того, как правильно соединить Django и React.

React: практики, которые помогут стать продвинутым разработчикомtproger.ru

Должен ли роутер React взять на себя маршрутизацию? Нужно ли монтировать компоненты React в каждом шаблоне Django?

Ответ зависит от случая.

Есть следующие способы создания проекта на Django и React (они похожи почти для любого веб-фреймворка):

  1. React в собственном приложении Django для фронтенда. Загружаем один HTML шаблон и даём React управление фронтендом (сложность: средняя).
  2. Django REST как отдельное API + React как отдельное SPA (сложность: высокая, нужна будет авторизация по JWT).
  3. Смешанный вариант: мини-приложения React в шаблонах Django (сложность: просто, но сложно будет поддерживать).

Если вы только начали работать с Django REST и React, избегайте варианта 2. Вместо этого выберите 1 (React в собственном приложении Django для фронтенда), если:

  • вы создаёте приложение, похожее на веб-сайт;
  • в интерфейсе будет много пользовательских действий, используется AJAX;
  • вас устраивает авторизация, основанная на сессиях;
  • вас не очень волнуют вопросы SEO;
  • вас устраивает роутер React.

Если будете держать React близко к Django, то будет проще с авторизацией. Можно будет использовать встроенную систему авторизации Django для регистрации и входа пользователей. Используйте старую добрую авторизацию с помощью сессий и не беспокойтесь о токенах и JWT.

Выберите вариант 3 (смешанный вариант: мини-приложения React в шаблонах Django), если:

  • на сайте не нужно использовать много JavaScript;
  • вам важно SEO и вы не можете использовать Node.js для рендеринга серверной части.

В данной статье мы будем использовать вариант 1.

Устанавливаем React и webpack

Создадим новое приложение Django для фронтенда:

django-admin startapp frontend

Вы увидите новую папку с названием frontend в вашей структуре папок:

(venv) your@prompt:~/Code/django-react$ tree -d -L 1 . ├── django_react ├── frontend ├── leads └── venv

Подготовим папки для хранения компонентов React:

mkdir -p ./frontend/src/components

И статики:

mkdir -p ./frontend/{static,templates}/frontend

Дальше установим React, webpack и babel. Перейдите в папку frontend и создайте окружение:

cd ./frontend && npm init -y

Установите webpack и webpack CLI:

npm i webpack webpack-cli --save-dev

Откройте package.json и запишите 2 скрипта для продакшна и для разработки:

"scripts": {   "dev": "webpack --mode development ./src/index.js --output ./static/frontend/main.js",   "build": "webpack --mode production ./src/index.js --output ./static/frontend/main.js" }

Сохраните и закройте файл.

Установим babel, чтобы код был совместим со старыми браузерами, которые не поддерживают последние стандарты JavaScript:

npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev

Установим React:

npm i react react-dom --save-dev

Настроим Babel (по-прежнему находясь в папке frontend):

{     "presets": [         "@babel/preset-env", "@babel/preset-react"     ] }

Создадим файл webpack.config.js для настройки загрузчика babel:

module.exports = {   module: {     rules: [       {         test: /.js$/,         exclude: /node_modules/,         use: {           loader: "babel-loader"         }       }     ]   } };

Готовим приложение Django для фронтенда

Создадим представление в ./frontend/views.py:

from django.shortcuts import render   def index(request):     return render(request, 'frontend/index.html')

Создадим шаблон в ./frontend/templates/frontend/index.html:

<!DOCTYPE html> <html> <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1">   <title>Django REST with React </head> <body> <div id="app">     <!-- React will load here --> </div> </body> {% load static %} <script src="{% static "frontend/main.js" %}"></script> </html>

В шаблоне вызывается ./frontend/main.js — файл, который будет генерировать webpack, содержащий весь код на React.

Настроим маршрутизатор Django: включим туда url приложения frontend. Отредактируем файл ./project/urls.py:

urlpatterns = [     path('', include('leads.urls')),     path('', include('frontend.urls')), ]

Создадим файл ./frontend/urls.py:

from django.urls import path from . import views   urlpatterns = [     path('', views.index ), ]

Включим приложение фронтенда в список используемых приложений в файле ./project/settings.py:

# Application definition  INSTALLED_APPS = [     'leads.apps.LeadsConfig',     'rest_framework',     'frontend', # enable the frontend app ]

Зайдя на http://127.0.0.1:8000/, вы увидите пока что просто пустую страницу (для этого сервер Django должен продолжать работать).

Фронтенд на React

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

Запустите сервер Django и перейдите на http://127.0.0.1:8000/api/lead/ чтобы добавить контакты.

Создадим файл ./frontend/src/components/App.js. В нём будет компонент React, запрашивающий и отображающий данные.

import { render } from "react-dom";  class App extends Component {   constructor(props) {     super(props);     this.state = {       data: [],       loaded: false,       placeholder: "Loading"     };   }    componentDidMount() {     fetch("api/lead")       .then(response => {         if (response.status > 400) {           return this.setState(() => {             return { placeholder: "Something went wrong!" };           });         }         return response.json();       })       .then(data => {         this.setState(() => {           return {             data,             loaded: true           };         });       });   }    render() {     return (       <ul>         {this.state.data.map(contact => {           return (             <li key={contact.id}>               {contact.name} - {contact.email}             </li>           );         })}       </ul>     );   } }  export default App;  const container = document.getElementById("app"); render(<App />, container);

Примечание можно написать тот же компонент в виде функции с хуком useEffect.

Сохраните и закройте файл. Теперь создайте точку входа для webpack — файл ./frontend/src/index.js и импортируйте компонент:

import App from "./components/App";

Теперь можно протестировать результат. Запустите webpack:

npm run dev

Запустите сервер Django:

python manage.py runserver

Перейдите на http://127.0.0.1:8000/. Если вы видите сообщение «Что-то пошло не так», то убедитесь, что применили миграции и заполнили базу данных. Вы должны увидеть данные, отображенные компонентом React.

sozdajom veb prilozhenie s bekendom na django i frontendom na react d1a1ab6 - Создаём веб-приложение с бэкендом на Django и фронтендом на React

Выглядит просто. И работает!

Заключение

В этом материале мы сделали простой проект на Django REST API и React. Мы научились:

  • создавать простое REST API на Django;
  • добавлять React в проект Django;
  • соединять Django REST API и React.

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Honor Cup, бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации

  • 1 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Свежие комментарии

    Рубрики

    About Author 01.

    Roman Spiridonov
    Roman Spiridonov

    Привет ! Мне 38 лет, я работаю в области информационных технологий более 4 лет. Тут собрано самое интересное.

    Our Instagram 04.

    Categories 05.

    © Speccy 2020 / All rights reserved

    Связаться со мной
    Close