Недавно я сделал проект с использованием 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.py
file:
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