Men yaqinda Django va React yordamida loyiha qildim. Ilgari men Django bilan tanish bo'lganman, lekin reaksiyaga kirishmaganman, bu meni kichik muammolar bilan shug'ullanishga majbur qildi. Shu munosabat bilan men React bilan ilovalar ishlab chiqishni va Reactni Django bilan qanday integratsiya qilishni o'rgandim. Shuning uchun men o'rganganlarimni baham ko'raman va siz ham foyda olasiz degan umiddaman!
Biz Movie-Rater-App bo'lgan oddiy dasturni yaratamiz, unda CRUD operatsiyalari mavjud. Aytishim kerakki, men hozirda Django 3.0.1 va ReactJS 6.13 bilan ishlayman.

Django o'rnatilmoqda

Avvalo, biz virtual muhitimizni sozlashimiz kerak. Bu yerda virtual muhitdan foydalanaman, virtualvenv ni o'rnatganingizga ishonch hosil qiling, so'ngra loyihangiz bo'lishini va ishga tushirilishini xohlagan katalogga o'ting:

$ pip install virtualenv
$ cd ur_project_folder

Buni tugatgandan so'ng, virtual muhitni quyidagi bilan faollashtiring:

$ virtualenv venv
$ source venv/bin/activate

Endi biz ba'zi paketlarni, jumladan, "Django", "Django REST Framework" va "Django CORS sarlavhalarini" o'rnatishimiz kerak. DRF bu bizning loyihamizni API ga aylantirish uchun Django ustiga qo'yadigan narsadir va Django CORS sarlavhalari mening resurslarimga mening frontendimda kirishga ruxsat berish uchun zarur:

pip install django
pip install djangorestframework
pip install django-cors-headers

Bu bajarilgach, biz Django loyihasini yaratishga tayyormiz. Quyidagilarni ishga tushiring:

django-admin startproject movierater
django-admin startapp api
python3 manage.py runserver

Endi api/urls.py ga o'ting va quyidagi o'zgartirishlarni kiriting:

#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)),
]

Bu erda men qilgan har bir qadam uchun sharh raqamini beraman, lekin men tasvirlab beraman, bu har bir bajarilgan fayl uchun koddir. Keyin movierater/urls.pyfaylni ham o'zgartiring:

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
]

Autentifikatsiya tokeni foydalanuvchi nomidan shifrlash kodini mahalliy xotirada saqlash uchun ishlatiladi, shunda foydalanuvchi kirish ma'lumotlari himoyalanadi. keyin, MovieRater loyihasida insetting.py quyidagi kodni qo'shing:

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',
]

Keling, MovieRater elementlari ma'lumotlar bazasida qanday saqlanishi kerakligini aniqlash uchun model yarataylik, movierater/models.py faylini oching va uni ushbu parcha bilan yangilang:

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

Yuqoridagi kod parchasi MovieRater modelidagi Movie sinfidagi to'rtta xususiyatni va Reyting sinfidagi uchta xususiyatni tavsiflaydi. Keyinchalik, biz ko'chirishni amalga oshirishimiz va fayl o'zgarishlarini ma'lumotlar bazasiga qo'llashimiz kerak, shuning uchun quyidagi buyruqlarni bajaramiz:

$ python3 manage.py makemigrations api
$ python3 manage.py migrate api

Biz CRUD operatsiyalari Django qutidan tashqarida taqdim etgan administrator interfeysi yordamida biz yaratgan movierater api modelida ishlashini tekshirishimiz mumkin, lekin birinchi navbatda biz biroz konfiguratsiya qilamiz.

api/admin.py faylini oching va mos ravishda yangilang:

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

Biz administrator interfeysiga kirish uchun superuser hisobini yaratamiz.

$ python3 manage.py createsupersuser

biz manzilga kirishga harakat qilishimiz mumkin:

Keyin, biz api/serializers.py faylini ochishimiz va uni quyidagi kod bilan yangilashimiz kerak:

#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')

biz api/view.py da ko'rish sinfini yaratamiz va quyidagi o'zgartirishlarni kiritamiz:

#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 fayliga o'ting va uni quyidagi kod bilan qo'shing. Ushbu kod API uchun URL yo'lini belgilaydi:

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

Bu API qurilishini yakunlovchi yakuniy bosqich, endi biz MovieRater modelida CRUD operatsiyalarini bajarishimiz mumkin.

Reaksiyani sozlash

biz frontendni yaratamiz va uni biz yaratgan interfeys orqali backend bilan bog'laymiz. Keyin ishga tushiring:

$ npx install create-react-app movie-rater-app
$ npm start

Ushbu loyihada men ushbu reaksiya kutubxonasini o'rnatdim va foydalandim:

Autentifikatsiya uchun react-cookie-fayllardan, piktogramma biriktirish uchun react-fontawesome va brauzer routeri uchun react-router-domdan foydalanaman.

Keling, komponentlar papkasini yaratamiz, /login.js yaratamiz va uni quyidagi kod bilan qo'shamiz:
https://gist.github.com/asaddam/7eead5c8a3c583fca165c6a348550ac1.js

Keyinchalik, film tafsilotlari uchun ba'zi shakllarni aniqlaylik. components, movieDetails.js, movieForm.jsva movieList.js ichida uchta yangi fayl yarating:

Biz src/App.js-ni oxirgi marta o'zgartiramiz, shunda u backend serverdan ma'lumotlarni so'raydi va ularning o'rniga ularni ro'yxatga oladi. Shuningdek, biz barcha CRUD operatsiyalari maʼlumotlar bilan oʻzaro aloqada boʻlish oʻrniga backend serveriga soʻrov yuborishini taʼminlashni istaymiz.

Faylni oching va uni ushbu oxirgi versiya bilan almashtiring:

Tabriklaymiz! Biz hozirgina frontendni muvaffaqiyatli qurdik.

Biz ushbu qo'llanmaning oxiriga keldik va bir-birimiz bilan to'g'ri ishlash uchun Django va Reactni qanday sozlashni o'rgandik.

Ushbu qoʻllanmaning manba kodi bu yerda mavjud va siz “bu yerda” ilovasini sinab koʻrishingiz mumkin:

Backend: "https://github.com/asaddam/movieRaterApp-django-backend"

FrontEnd: https://github.com/asaddam/movieRaterApp-React-Frontend