Am realizat recent un proiect folosind Django și React. anterior eram familiarizat cu Django, dar nu cu React, făcându-mă să mă ocup de mici probleme în a face asta. Cu această ocazie, am învățat să dezvolt aplicații cu React și cum să integrez React cu Django. Așa că vă împărtășesc ceea ce am învățat, în speranța că veți obține și un beneficiu!
Vom realiza o aplicație simplă care este Movie-Rater-App care are operațiuni CRUD în ea. Trebuie să menționez că în prezent lucrez cu Django 3.0.1 și ReactJS 6.13.
Configurarea Django
În primul rând, trebuie să ne configuram mediul virtual. Voi folosi mediul virtual aici, asigurați-vă că ați instalat virtualvenv, apoi navigați la directorul în care doriți să fie proiectul și rulați:
$ pip install virtualenv $ cd ur_project_folder
După ce ați terminat, activați mediul virtual cu:
$ virtualenv venv $ source venv/bin/activate
Acum va trebui să instalăm câteva pachete, inclusiv Django, Django REST framework și Django CORS headers. DRF este ceea ce vom pune peste Django pentru a ne transforma proiectul într-un API, iar anteturile Django CORS sunt necesare pentru a permite accesul resurselor mele pe front-end:
pip install django pip install djangorestframework pip install django-cors-headers
Odată ce acest lucru este făcut, suntem gata să creăm proiectul Django. Rulați următoarele:
django-admin startproject movierater django-admin startapp api python3 manage.py runserver
Acum, intrați în api/urls.py
și faceți următoarele modificări:
#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)), ]
Aici ofer un număr de comentariu pentru fiecare pas pe care l-am făcut, dar ceea ce voi descrie este codul pentru fiecare fișier care a fost finalizat. Apoi, modificați și fișierul_2:
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 ]
Tokenul de autentificare este folosit pentru a stoca codul de criptare de la numele de utilizator în stocarea locală, astfel încât datele de acces ale utilizatorului să fie securizate. apoi, în proiectul MovieRater însetting.py
adăugați codul după cum urmează:
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', ]
Să creăm un model pentru a defini modul în care articolele MovieRater ar trebui să fie stocate în baza de date, să deschidem fișierul movierater/models.py
și să-l actualizăm cu acest fragment:
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
Fragmentul de cod de mai sus descrie patru proprietăți din clasa Movie și trei proprietăți din clasa Rating pe modelul MovieRater. În continuare, trebuie să facem o migrare și să aplicăm modificările fișierului în baza de date, așa că haideți să rulăm aceste comenzi:
$ python3 manage.py makemigrations api $ python3 manage.py migrate api
Putem testa pentru a vedea că operațiunile CRUD funcționează pe modelul API movierater pe care l-am creat folosind interfața de administrare pe care Django o oferă din cutie, dar mai întâi, vom face o mică configurare.
Deschideți fișierul api/admin.py
și actualizați-l în consecință:
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
Vom crea un cont de superutilizator pentru a accesa interfața de administrare.
$ python3 manage.py createsupersuser
putem încerca să ne logăm la adresa:
Apoi, trebuie să deschidem fișierul api/serializers.py
și să-l actualizăm cu următorul cod:
#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')
vom crea clasa de vizualizare în api/view.py
și vom face următoarele modificări:
#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)
Mergeți la fișierul api/urls.py
și adăugați-l cu codul de mai jos. Acest cod specifică calea URL pentru 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
Acesta este pasul final care completează construirea API-ului, acum putem efectua operațiuni CRUD pe modelul MovieRater.
Configurarea React
ne vom crea frontend-ul și îl vom face să comunice cu backend-ul prin interfața pe care am creat-o. Apoi rulați:
$ npx install create-react-app movie-rater-app $ npm start
În acest proiect, am instalat și am folosit această bibliotecă react:
Folosesc react-cookie pentru autentificare, react-fontawesome pentru atașarea pictogramei și react-router-dom pentru routerul browserului.
Să facem un folder de componente, să creăm /login.js
și să-l adăugăm cu acest cod de mai jos:
https://gist.github.com/asaddam/7eead5c8a3c583fca165c6a348550ac1.js
În continuare, să definim câteva forme pentru detaliile filmului. Creați trei fișiere noi în components
, movieDetails.js,
movieForm.js
și movieList.js
:
Vom modifica src/App.js pentru ultima dată, astfel încât acesta va solicita date de la serverul de backend și le va lista în schimb. De asemenea, dorim să ne asigurăm că toate operațiunile CRUD trimit cereri către serverul de backend în loc să interacționeze cu datele.
Deschideți fișierul și înlocuiți-l cu această versiune finală:
Felicitări! Tocmai am construit frontend-ul cu succes.
Am ajuns la sfârșitul acestui tutorial și am învățat cum să configuram Django și React pentru a interacționa corect unul cu celălalt.
Codul sursă pentru acest tutorial este disponibil aici și puteți încerca aplicația „aici”:
Backend: https://github.com/asaddam/movieRaterApp-django-backend
FrontEnd: https://github.com/asaddam/movieRaterApp-React-Frontend