
Недавно я сделал проект с использованием Django и React. ранее я был знаком с Django, но не с React, что заставляло меня сталкиваться с небольшими проблемами при этом. В связи с этим я научился разрабатывать приложения с помощью React и интегрировать React с Django. Итак, я делюсь тем, что узнал, в надежде, что вы также получите пользу!
Мы создадим простое приложение Movie-Rater-App, в котором есть операции CRUD. Я должен упомянуть, что в настоящее время я работаю с Django 3.0.1 и ReactJS 6.13.
Настройка Джанго
Прежде всего, нам нужно настроить нашу виртуальную среду. Здесь я буду использовать виртуальную среду, убедитесь, что вы установили virtualvenv, затем перейдите в каталог, в котором вы хотите разместить свой проект, и запустите его:
$ pip install virtualenv $ cd ur_project_folder
Как только это будет сделано, активируйте виртуальную среду с помощью:
$ virtualenv venv $ source venv/bin/activate
Теперь нам нужно установить некоторые пакеты, в том числе Django, Django REST framework и Django CORS headers. DRF — это то, что мы будем накладывать поверх Django, чтобы превратить наш проект в API, а заголовки Django CORS необходимы, чтобы разрешить доступ к моим ресурсам в моем интерфейсе:
pip install django pip install djangorestframework pip install django-cors-headers
Как только это будет сделано, мы готовы создать проект Django. Запустите следующее:
django-admin startproject movierater django-admin startapp api python3 manage.py runserver
Теперь перейдите в api/urls.py и внесите следующие изменения:
#1
from django.urls import path
from rest_framework import routers
from django.conf.urls import include
router = routers.DefaultRouter()urlpatterns = [
path('', include(router.urls)),
]
Здесь я привожу номер комментария для каждого шага, который я сделал, но я опишу код для каждого завершенного файла. Затем также измените themovierater/urls.pyfile:
from django.contrib import admin
from django.urls import path
from django.conf.urls import include # 2 new line
from rest_framework.authtoken.views import obtain_auth_token #11
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')), # 3 new line
path('auth/', obtain_auth_token), # 11
]
Токен аутентификации используется для хранения кода шифрования из имени пользователя в локальном хранилище, чтобы данные доступа пользователя были защищены. затем в проекте MovieRater insetting.py добавьте следующий код:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', #4
'rest_framework.authtoken',#10 make login
'corsheaders', # to connect to front end
'api', #4
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', #cors
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Давайте создадим модель для определения того, как элементы MovieRater должны храниться в базе данных, откроем файл movierater/models.py и обновим его с помощью этого фрагмента:
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
# Create your models here. 5
class Movie(models.Model):
title = models.CharField(max_length=32)
description = models.TextField(max_length=360)
#9
def no_of_ratings(self):
ratings = Rating.objects.filter(movie=self)
return len(ratings)
def avg_rating(self):
ratings = Rating.objects.filter(movie=self)
sum = 0
for rating in ratings:
sum += rating.stars
if len(ratings) > 0:
return sum / len(ratings)
else:
return 0
class Rating(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
class Meta:
unique_together = (('user', 'movie'),)
index_together = (('user', 'movie'),)
# do makemigrations and migrate
Фрагмент кода выше описывает четыре свойства в классе Movie и три свойства в классе Rating в модели MovieRater. Далее нам нужно выполнить миграцию и применить изменения файла к базе данных, поэтому давайте запустим эти команды:
$ python3 manage.py makemigrations api $ python3 manage.py migrate api
Мы можем проверить, работают ли операции CRUD с моделью API Movierater, которую мы создали, используя интерфейс администратора, который Django предоставляет из коробки, но сначала мы выполним небольшую настройку.
Откройте файл api/admin.py и обновите его соответствующим образом:
from django.contrib import admin from .models import Movie, Rating #6 make register # Register your models here. admin.site.register(Movie) #6 new line admin.site.register(Rating) #6 new line
Мы создадим учетную запись суперпользователя для доступа к интерфейсу администратора.
$ python3 manage.py createsupersuser
мы можем попробовать войти по адресу:

Затем нам нужно открыть файл api/serializers.py и обновить его следующим кодом:
#7
from rest_framework import serializers
from .models import Movie, Rating
from django.contrib.auth.models import User #14
from rest_framework.authtoken.models import Token #17
#14 for register and login
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password')
extra_kwargs = {'password': {'write_only': True, 'required': True}}
#16 validate data
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
Token.objects.create(user=user)
return user
class MovieSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = ('id', 'title', 'description', 'no_of_ratings', 'avg_rating')
class RatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
fields = ('id', 'stars', 'user', 'movie')
мы создадим класс представления в api/view.py и внесем следующие изменения:
#13
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (AllowAny, )
# Create your views here. 7
class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
authentication_classes = (TokenAuthentication, ) #12
permission_classes = (IsAuthenticated, ) #19
#8
@action(detail=True, methods=['POST'])
def rate_movie(self, request, pk=None):
if 'stars' in request.data:
movie = Movie.objects.get(id=pk)
stars = request.data['stars']
user = request.user #12
try:
rating = Rating.objects.get(user=user.id,
movie=movie.id)
rating.stars = stars
rating.save()
serializer = RatingSerializer(rating, many=False)
response = {'message': 'rating updated', 'result': serializer.data}
return Response(response, status=status.HTTP_200_OK)
except:
rating = Rating.objects.create(user=user, movie=movie, stars=stars)
serializer = RatingSerializer(rating, many=False)
response = {'message': 'rating created', 'result': serializer.data}
return Response(response, status=status.HTTP_200_OK)
else:
response = {'message': 'you need to provide stars'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
class RatingViewSet(viewsets.ModelViewSet):
queryset = Rating.objects.all()
serializer_class = RatingSerializer
authentication_classes = (TokenAuthentication, ) #12
permission_classes = (IsAuthenticated, ) #19
#20
def update(self, request, *args, **kwargs):
response = {'message': 'you cant update rating like that'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs):
response = {'message': 'you cant create rating like that'}
return Response(response, status=status.HTTP_400_BAD_REQUEST)
Перейдите к файлу api/urls.py и добавьте его с помощью приведенного ниже кода. Этот код указывает URL-адрес для API:
from .views import MovieViewSet, RatingViewSet, UserViewSet #8 15userviewset
router.register('movies', MovieViewSet) #8
router.register('ratings', RatingViewSet) #8
router.register('users', UserViewSet) #15 for register and login
Это последний шаг, который завершает создание API, теперь мы можем выполнять операции CRUD с моделью MovieRater.
Настройка React
мы создадим наш интерфейс и заставим его общаться с сервером через созданный нами интерфейс. Затем запустите:
$ npx install create-react-app movie-rater-app $ npm start
В этом проекте я установил и использую эту библиотеку реагирования:

Я использую react-cookie для аутентификации, react-fontawesome для прикрепления значка и react-router-dom для маршрутизатора браузера.
Давайте создадим папку компонентов, создадим /login.js и добавим ее с помощью этого кода ниже:
https://gist.github.com/asaddam/7eead5c8a3c583fca165c6a348550ac1.js
Далее, давайте определим некоторые формы для деталей фильма. Создайте три новых файла в components, movieDetails.js, movieForm.jsи movieList.js:
Мы изменим src/App.js в последний раз, чтобы он запрашивал данные с внутреннего сервера и вместо этого перечислял их. Мы также хотим убедиться, что все операции CRUD отправляют запросы на внутренний сервер, а не взаимодействуют с данными.
Откройте файл и замените его этой окончательной версией:
Поздравляем! Мы только что успешно построили интерфейс.
Мы подошли к концу этого руководства и узнали, как настроить Django и React для правильного взаимодействия друг с другом.
Исходный код этого туториала доступен здесь, а попробовать приложение можно здесь:
Бэкенд: https://github.com/asaddam/movieRaterApp-django-backend
Внешний интерфейс: https://github.com/asaddam/movieRaterApp-React-Frontend