깃허브에서 zip 다운, 압축풀기
node js 설치 후 cmd에서 node -v 로 확인
cmd
src → config.js 파일 열어 SERVER, CARTSERVER 우리 장고 서버 127.0.0.1로 바꿈
상품이랑 리뷰 관계 맺기
model에 product 추가 후 migrate
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
# Create your models here.
from rest_framework.authtoken.admin import User
from product.models import Product
class Review(models.Model):
score = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)]) # 0최소값, 5최대값으로 설정해 리뷰 0~5점까지 받도록
contents = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
writer = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
그 모델에 있냐 기준으로 코드가 달라짐(prefetcch랑 selected처럼)
1:N 관계일때
forigen key를 N측에 넣었었음
1측을 기준으로 N측을 같이 조회
N측을 기준으로 1측을 같이 조회
자동으로 serializer가 prefetch 명령어를 수행한다
from rest_framework import serializers
from product.models import Product
from review.serializer import ReviewSerializer
# 상품등록할때 리뷰는 등록안해도 되게 읽기전용으로
class ProductSerializer(serializers.ModelSerializer):
review_set = ReviewSerializer(many=True, read_only=True) # 리뷰 여러개 달릴 수 있음
class Meta:
model = Product
fields = ['name','description','price','review_set']
serializer를 여러개 둘 수도 있음
리뷰달때 상품 선택할 수 있음. 리뷰 여러개 등록해서 상품 조회해보면 리뷰 같이 볼 수 있음
내가 몇번 상품의 리뷰다 라는걸 전달해줘야함
?로 하는거 - 쿼리
경로상으로 하는 방식 (url)
json타입에 써서 보내는 방식
review_set_coount 추가해서 썸네일에 숫자 보이게하려면 product serializer 추가
from rest_framework import serializers
from product.models import Product
from review.serializer import ReviewSerializer
# 상품등록할때 리뷰는 등록안해도 되게 읽기전용으로
class ProductSerializer(serializers.ModelSerializer):
review_set = ReviewSerializer(many=True, read_only=True) # 리뷰 여러개 달릴 수 있음
review_set_count = serializers.IntegerField(source='review_set.count', read_only=True) # count 보여주는거 만들음
class Meta:
model = Product
fields = ['name','description','price','review_set', 'review_set_coount']
order 앱추가 모델만들기
order models.py
from django.db import models
# Create your models here.
from rest_framework.authtoken.admin import User
from product.models import Product
class Order(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)# 상품과 관계맺기
user = models.ForeignKey(User,on_delete=models.CASCADE)#유저와 관계맺기
order serializer 만들기
from rest_framework import serializers
from order.models import Order
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = '__all__'
order views
from django.shortcuts import render
# Create your views here.
from rest_framework import viewsets
from order.models import Order
from order.serializer import OrderSerializer
class OrderViewSet(viewsets.ModelViewSet):
queryset = Order.objects.all()
serializer_class = OrderSerializer
order urls
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
import order.views
router = DefaultRouter()
router.register('order', order.views.OrderViewSet) # viewset이 만든 여러 메소드의 url을 만들어줌
urlpatterns = [
path('', include(router.urls))
]
config urls
path('', include('order.urls')),
관리자페이지 등록 후 order 몇개 등록해놓기
주문을 기준으로 사용자나 상품 뽑아낼것임
상품1 N주문 M 1사용자
주문이라는 애 기준으로 1측(사용자), 1측(상품)을 뽑아내는 것임(prefetch가 아니라 selected인)
이걸 여기서 하려면
from rest_framework import serializers
from rest_framework.authtoken.admin import User
from order.models import Order
from product.models import Product
from product.serializer import ProductSerializer
class OrderProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ['name', 'price', 'seller'] # 이 3개만 출력하는 Serializer를 만들음
class OrderUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', ] # 뽑아내고싶은거만 serializer를 만들어줌
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = '__all__'
def to_representation(self, instance): # instance에는 조회하고싶은 것. product user 둘다 order에 있으니까 (정방향조회)
response = super().to_representation(instance) #상속받은 원래 representaion객체 (숫자만 띵 써있던)
response['product'] = OrderProductSerializer(instance.product).data #모델 안에 들어있는 product를 전달해서 원하는것(serializer에 지정해놓은것)만 뽑아줌
response['user'] = OrderUserSerializer(instance.user).data # 유저는 원래 시리얼라이저 생성안해놨어서 위에다가 만들기
return response
from django.shortcuts import render
# Create your views here.
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from order.models import Order
from order.serializer import OrderSerializer
class OrderViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = Order.objects.all()
serializer_class = OrderSerializer
def get_queryset(self):
qs = super().get_queryset() # 부모 거 그대로 가져온 것
qs = qs.filter(user=self.request.user)
return qs
프론트에서의 product_detail json과 형식 같게 맞추어주기
모델 수정
from django.db import models
# Create your models here.
from rest_framework.authtoken.admin import User
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
seller = models.ForeignKey(User, on_delete=models.CASCADE)
discount_percentage = models.IntegerField()
is_free_delivery = models.BooleanField()
is_on_sale = models.BooleanField()
class ProductImage(models.Model):
image = models.ImageField(upload_to='images/product/', blank=True)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
serializer
from rest_framework import serializers
from product.models import Product, ProductImage
from review.serializer import ReviewSerializer
# 이미지 가져오기 위한 serializer 만들기
class ProductImageSerializer(serializers.ModelSerializer):
class Meta:
model = ProductImage
fields = ['image',]
# 상품등록할때 리뷰는 등록안해도 되게 읽기전용으로
class ProductSerializer(serializers.ModelSerializer):
review_set = ReviewSerializer(many=True, read_only=True) # 리뷰 여러개 달릴 수 있음
review_count = serializers.IntegerField(source='review_set.count', read_only=True) # count 보여주는거 만들음
productimage_set = ProductImageSerializer(many=True, read_only=False)
class Meta:
model = Product
fields = ['id','name', 'review_count','review_set','discount_percentage','is_free_delivery','is_on_sale',]
# 재정의해서 출력을 다르게 해줄것임
def to_representation(self, instance):
response = super().to_representation(instance)
response['company'] = instance.seller.username #우리는 seller였는데 저기서는 이름이 company였으니까 이렇게 지정해줌
response['image'] = response['productimage_set'][0]['image'] #이미지 중 첫번째의 이미지
# 할인 가격 = 원래가격 * (100-할인율) // 100
response['discount_price'] = instance.price * (100-instance.discount_percentage) // 100
# review 평균 계산
if response['review_count']!=0:
total = 0
for review in instance.review_set.all():
total += review.score
response['rate_average'] = round(total // response['review_count'],1) # 1자리까지 올림
else :
response['rate_average'] = 0
return response
/product/
요청받는곳, 주는 곳이 다르면 cross origin error가 생김
CORS 설정을 추가해줘야함
pip install django-cors-headers
settings,py INSTALLED_APP에 추가
'corsheaders',
settings.py MIDDLEWARE에 추가
'corsheaders.middleware.CorsMiddleware',
CORS_ORIGIN_WHITELIST = ['http://127.0.0.1:3000','http://localhost:3000'] # 이 안에 해당하는건 허용, 배포 시에는 바꿔줘야함. 도메인 같은 게 들어가는것
CORS_ALLOW_CREDENTIALS = True