1st Project [ wesop! ] -2 CODE Review - My code


このプロジェクトでは、チームメンバーと一緒にproductapiを担当しています.幸いバックエンドチームメンバーはやる気満々な人ばかりで、機能はうまくいっていますが、お互いに書いたコードを共有する時間がなくて、本当に残念です...私たちHOT SANと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ができたようで、とても気持ちがいいです.