1st Project [ wesop! ] -2 CODE Review - My code
이번 프로젝트에서는 팀원 한분과 함께 product api를 맡아서 하게되었다. 다행이 백엔드 팀원분들이 모두 열의가 넘치는 분들이라 기능은 잘 구현했지만 서로 쓴 코드를 공유할 수 있는 시간이 없어서 너무 아쉬웠다... 우리 핫산 님과 11시 요정은 저의 첫 러닝 메이트 였습니다...😌
Models.py
from itertools import product
from django.db import models
from users.models import User
from cores.timestamp import TimeStamp
# Create your models here.
class Product(TimeStamp):
name = models.CharField(max_length=45)
price = models.DecimalField(decimal_places=2, max_digits=10)
size = models.CharField(max_length=45)
description = models.TextField(max_length=1000)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
howtouse = models.JSONField()
feelings = models.ManyToManyField('Feeling', through="ProductFeelings")
badge = models.CharField(max_length=15, null=True)
skin_types = models.ManyToManyField('SkinType', through='ProductSkintype')
class Meta:
db_table = 'products'
class Feeling(models.Model):
name = models.CharField(max_length=30)
class Meta:
db_table = 'feelings'
class ProductFeelings(models.Model):
product = models.ForeignKey('Product' , on_delete=models.CASCADE)
feeling = models.ForeignKey('Feeling' , on_delete=models.CASCADE)
class Meta:
db_table = 'product_feelings'
class Category(models.Model):
category_name = models.CharField(max_length=45)
main_description = models.CharField(max_length=1000, null=True)
sub_description = models.CharField(max_length=1000, null=True)
class Meta:
db_table = 'categories'
class Ingredient(models.Model):
name = models.CharField(max_length=300)
class Meta:
db_table = 'ingredients'
class ProductIngredient(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE)
ingredient = models.ForeignKey('Ingredient', on_delete=models.CASCADE)
major = models.BooleanField(default=False)
class Meta:
db_table = 'product_ingredients'
class ProductImage(models.Model):
url = models.CharField(max_length=2000)
product = models.ForeignKey('Product', on_delete=models.CASCADE)
class Meta:
db_table = 'product_imgaes'
class SkinType(models.Model):
name = models.CharField(max_length=45)
class Meta:
db_table = 'skin_types'
class ProductSkintype(models.Model):
product = models.ForeignKey('Product', on_delete=models.CASCADE)
skin_type = models.ForeignKey('SkinType', on_delete=models.CASCADE)
class Meta:
db_table = 'product_skintypes'
class Review(TimeStamp):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='users')
product = models.ForeignKey('Product' , on_delete=models.CASCADE, related_name='products')
content = models.CharField(max_length=400)
class Meta:
db_table = 'reviews'
class ReviewImage(models.Model):
review = models.ForeignKey('Review' , on_delete=models.CASCADE , related_name='reviews')
image_url = models.CharField(max_length=300)
class Meta:
db_table = 'review_images'
안써봤던 JSONField를 사용해보았다. 장고의 필드 내용들은 한번 쭈욱 정리가 필요하니 나중에 한번 다 정리를 해보려고한다.
product_detail_views
class ProductDetailView(View):
def get(self, request, product_id):
try:
product = Product.objects.get(id = product_id)
main_ingredients = Ingredient.objects.filter(productingredient__product_id = product.id, productingredient__major = True)
skin_type = SkinType.objects.filter(productskintype__product_id = product_id)
feelings = ProductFeelings.objects.filter(product = product_id)
product_detail = {
'id' : product.id,
'name' : product.name,
'price' : product.price,
'size' : product.size,
'category' : product.category.category_name,
'description' : product.description,
'feeling' : [feeling.feeling.name for feeling in feelings],
'product_imges' : [image.url for image in product.productimage_set.all()],
'main_ingredients' : [ingredient.name for ingredient in main_ingredients],
'ingredients' : [ingredient.name for ingredient in Ingredient.objects.filter(productingredient__product = product_id)],
'skin_type' : [type.name for type in skin_type]
}
howtouse = product.howtouse
return JsonResponse({'result' : [ product_detail , howtouse ] } , status = 200)
except KeyError:
return JsonResponse({'message' : 'KEY_ERROR'} , status = 404)
except Product.DoesNotExist:
return JsonResponse({'message' : 'PRODUCT_NAME_ERROR'} , status = 404)
Mysql을 알아야 ERD를 잘 알고 ERD에 대한 이해도가 높아야 좋은 api를 만들 수 있다... 누군가 시작점에서 내 블로그를 읽는 다면 무조건 기본을 하나하나 다져가며 공부하길 바란다.
product_recommend_view
class RecommendedView(View):
def get(self, request, product_id):
try:
category_id = Product.objects.get(id = product_id).category
products = Product.objects.filter(category = category_id).exclude(id=product_id)
recommend_list = [{
'name' : product.name,
'image' : [image.url for image in product.productimage_set.all()],
'skintype' : [types.skin_type.name for types in product.productskintype_set.all()]
} for product in products]
return JsonResponse({'result' : recommend_list }, status = 200)
except KeyError:
return JsonResponse({'message' : 'KEY_ERROR'} , status = 401)
except Product.DoesNotExist:
return JsonResponse({'message' : 'PRODUCT_DOES_EXIST'} , status = 401)
product_review_view
class ProductReviewView(View):
def get(self, request):
try:
data = json.loads(request.body)
reviews =Review.objects.filter(product_id = data['product_id'])
if not reviews.exists():
return JsonResponse({'message' : 'PRODUCT_REVIEW_DOES_NOT_EXIST'} , status = 404)
result = [{
'review_id' : review.id,
'user' : review.user.email,
'content' : review.content
} for review in reviews]
return JsonResponse({'message' : result} , status =200)
except KeyError:
return JsonResponse({'message': 'KEY_ERROR'} , status = 400)
except Product.DoesNotExist:
return JsonResponse({'message' : 'PRODUCT_DOES_NOT_EXIST'} , status = 400)
@author
def post(self, request):
try:
data = json.loads(request.body)
content = data['content']
user = request.user
product = Product.objects.get(id = data['product_id'])
Review.objects.create(
user = user,
product = product,
content = content
)
return JsonResponse({'message' : 'SUCCESS'} , status = 201)
except KeyError:
return JsonResponse({'message': 'KEY_ERROR'} , status = 400)
except Product.DoesNotExist:
return JsonResponse({'message' : 'PRODUCT_DOES_NOT_EXIST'} , status = 404)
@author
def delete(self, request, review_id):
review = Review.objects.filter(user = request.user , id = review_id)
if not review.exists():
return JsonResponse({'message' : 'UNAUTHORIZED_REQUEST'} , status = 404)
review.delete()
return JsonResponse({'message' : 'SUCCESS'} , status = 200)
게시판 기능 api 는 프로젝트의 사정상 빛을 볼 순 없었다. 뭔가 아쉬운 마음이 들기도 했지만 내 api가 빛을 볼 수 있도록 자신에 시간에서 최선을 다한 내 프론트 짝궁 Mr.MD의 모습을 봤기 때문에 기쁜 마음으로 다음 기약했다.
product_list_view (필터 기능 구현)
class ProductListView(View):
def get(self, request):
category_id = request.GET.get('category_id', None)
offset = int(request.GET.get('offset', 0))
limit = int(request.GET.get('limit', 100))
ingredient_id = request.GET.getlist('ingredient_id', None)
skintype_id = request.GET.getlist('skintype_id', None)
scent = request.GET.get('scent', None)
feeling_id = request.GET.get('feeling_id', None)
search = request.GET.get('search', None)
q = Q()
if search:
q &= Q(name__icontains=search)
if category_id:
q &= Q(category__id=category_id)
if scent:
q &= Q(howtouse__scent__contains=scent)
if ingredient_id:
q &= Q(productingredient__ingredient__id__in=ingredient_id)
if skintype_id:
q &= Q(productskintype__skin_type__id__in=skintype_id)
if feeling_id:
q &= Q(productfeelings__feeling__id__in=feeling_id)
products = Product.objects.filter(q)[offset:offset+limit]
result = [{
'id' : product.id,
'badge' : product.badge,
'productName': product.name,
'size' : product.size,
'price' : product.price,
'feeling' : [feeling.feeling.name for feeling in product.productfeelings_set.all()],
'ingredient' : [item.ingredient.name for item in product.productingredient_set.all()],
'skin_type' : [productskintype.skin_type.name for productskintype in product.productskintype_set.all()],
'url' : [img.url for img in product.productimage_set.all()],
'howtouse' : product.howtouse,
'category' : {
'categoryId' : product.category.id,
'categoryName' : product.category.category_name,
'categoryDescription' : product.category.main_description,
'categorySubDescription': product.category.sub_description
}
} for product in products]
return JsonResponse({'result':result}, status=200)
이 api는 다른 백엔드 분과 요이땅! 하고 만든 뒤 서로껄 합치면서 작성한 api이다. 다 만든 뒤 합치면서 더 성능이 좋은 api가 만들어 진것 같아 기분이 좋았다.
Author And Source
이 문제에 관하여(1st Project [ wesop! ] -2 CODE Review - My code), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@soohun9909/1st-Project-wesop-2-code저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)