セカンダリプリフェッチクローンプロジェクト


紹介する


Prepは、ナビゲーションから支払い、参加するアクティビティ、1日のカテゴリ、ソーシャルクラブ、旅行製品をWebサイトとアプリケーションを通じて提供します.

チーム要素の概要


チームメンバー:フロント2名、バックエンド3名
チーム名:梗-移動バージョン

モデリング



実装機能


User app
  • Kakaoソーシャルログイン
  • を実施
    Review app
  • aws 3を使ってコメントを書いて、コメントはとても良くて、コメントのコメント
  • を実現します
    Product app
  • ホームページ、製品詳細ページ、商品リストページ実現
  • Order app
  • ホームページ、ブックマークページ、ホームページ実装
  • 私が実施した機能🎉


    今回、チームメンバーは多くの譲歩を行い、2つのapiを使用してコメントとソーシャルログインを実現しました.

    KakaoSocialログイン

  • apiは初めて使用され、その中には多くの困難がある.まず、kakodeveloperのサイトで非常に詳細な内容を見ましたが、何度見ても論理をどのように書くべきか、tokenをどのように受け取るべきか分かりませんでしたが、今回フロントでコインを受け取り、バックグラウンドであることを知り、ユーザー情報を見た部分は、ソーシャルログインに関する文章がたくさんあり、お互いに参考になりました.職業を作った
  • 
    class KakaoSigninView(View):
        def post(self, request):
            try:
                access_token = request.headers.get("Authorization")
                
                if not access_token:
                    return JsonResponse({'message' : 'ACCESS_TOKEN_DOES_NOT_EXITS'}, status=401)
    
                headers   = ({'Authorization':f'Bearer {access_token}'})
                kakao_url = 'https://kapi.kakao.com/v2/user/me'
                response  = requests.get(kakao_url, headers = headers)
                user      = response.json()
                
                if not user:
                    return JsonResponse({'message' : 'INVALID_TOKEN'}, status=401)
    
                user, created = User.objects.get_or_create(
                    name          = user['kakao_account']['profile'].get('nickname'),
                    email         = user['kakao_account'].get('email'),
                    profile_image = user['kakao_account']['profile'].get('profile_image_url'),
                    origin_pk     = user.get('id')
                )
                
                result = {
                    'name'          : user.name,
                    'profile_image' : user.profile_image,
                    'email'         : user.email
                }
                token = jwt.encode({'id' : user.id}, SECRET_KEY, ALGORITHM)
                
                return JsonResponse({'token' : token, 'data' : result}, status = 201)
                
            except IntegrityError:
                return JsonResponse({'message' : 'INTEGRITY_ERROR'}, status=401)
    
            except KeyError:
                return JsonResponse({'message' : 'KEY_ERROR'}, status=400)

    コメント機能

  • コメントを作成すると、画像がdbデータを大量に占有するため、s 3に画像をアップロードすることで、s 3は論理で指定されたURLとなるため、db空間が減少する.s 3はboto 3を用いており,論理の記述が困難である.私たちはできるだけs 3がどのように働いているのかを理解して、いろいろな内容を応用して論理を書いてみました.最も重要なのはそれを私のものにすることだと思います.
  • class ReviewView(View):
        @login_decorator
        def post(self, request):
            try:
                user    = request.user
                content = request.POST['content']
                rating  = request.POST['rating']
                product = Product.objects.get(id=request.POST['product'])
                
                s3_client = boto3.client(
                    's3',
                    aws_access_key_id     = ACCESS_KEY,
                    aws_secret_access_key = SECRET_ACCESS_KEY
                )
                
                image      = request.FILES['filename']
                image_time = (str(datetime.now())).replace(" ","")
                image_type = (image.content_type).split("/")[1]                                     
                
                s3_client.upload_fileobj(
                    image,
                    "dripawsbucket21",
                    image_time+"."+image_type,
                    ExtraArgs = {
                        "ContentType" : image.content_type
                    }
                )
    
                image_url = "https://dripawsbucket21.s3.ap-northeast-2.amazonaws.com/"+image_time+"."+image_type
    
                Review.objects.create(
                    user      = user,
                    content   = content,
                    rating    = rating,
                    image_url = image_url if image else None,
                    product   = product,
                )
    
                return JsonResponse({'result' : 'SUCCESS'}, status = 201)
    
            except KeyError:
                return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)
    
        @login_decorator
        def get(self, request, product_id):
            try:
                user    = request.user
                order   = request.GET.get('order')
    
                order_conditions = {
                    'new' : '-created_at',
                    'old' : 'created_at',
                    'like' : '-like_count',
                    'unlike' : 'like_count',
                }
    
                reviews  = Review.objects.filter(product_id=product_id).annotate(like_count = Count('like')).order_by(order_conditions.get(order, '-created_at'))
                
                review_list = [{
                    'created_at'   : review.created_at,
                    'user'         : review.user.name,
                    'content'      : review.content,
                    'rating'       : review.rating,
                    'product'      : product_id,
                    'like_count'   : review.like_set.count(),
                    'review_count' : reviews.count(),
                    'image_url'    : review.image_url,
                    'like'         : Like.objects.filter(user_id = user.id, review_id = review.id).exists(),
                    'user_image'   : review.user.profile_image,
                    'avgrating' : reviews.aggregate(avgrating=Avg('rating'))
                    } for review in reviews]
                return JsonResponse({'result' : review_list, 'avgrating' : reviews.aggregate(avgrating=Avg('rating'))['avgrating']}, status = 200)
    
            except Product.DoesNotExist:
                return JsonResponse({"message" : 'DOES_NOT_EXIT_PRODUCT_ID'}, status = 401)
    
    class CommentView(View):
        @login_decorator
        def post(self, request):
            try:
                data    = json.loads(request.body)
                content = data['content']
                user    = request.user
                review  = Review.objects.get(id=data['review'])
            
                Comment.objects.create(
                    user    = user,
                    content = content,
                    review  = review
                )
                return JsonResponse({'message' : 'SUCCESS'}, status = 201)
            except KeyError:
                return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)
    
        @login_decorator
        def get(self, review_id):
            try:
                comment_list = [{
                    'user'    : comment_list.user.id,
                    'content' : comment_list.content,
                    'review'  : review_id
                }for comment_list in Comment.objects.filter(review_id = review_id)]
                
                return JsonResponse({'result' : comment_list}, status = 200)
            except Review.DoesNotExist:
                return JsonResponse({"message" : 'DOES_NOT_EXIT_REVIEW_ID'}, status = 401)
    
    class LikeView(View):
        @login_decorator
        def post(self, request):
            try:
                data      = json.loads(request.body)
                user      = request.user
                review_id = data['review_id']
    
                if not Review.objects.filter(id = review_id).exists():
                    return JsonResponse({'message' : 'INVALID_REVIEW'}, status = 401)
    
                if not Like.objects.filter(user = user, review_id = review_id).exists():
                    Like.objects.create(user = user, review_id = review_id)
                
                    return JsonResponse({'message' : 'SUCCESS'}, status= 201)
    
            except KeyError:
                return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)
    
        @login_decorator
        def delete(self, request, review_id):
            Like.objects.filter(user = request.user, review_id = review_id).delete()
    
            return JsonResponse({'message' : 'SUCCESS'},status = 204)
    

    コミュニケーション


    今回のプロジェクトは、タスク共有キー値、body値、pathなどを通じて、機能を実装する際に遅くまで完了することが多いが、フロントの理解により、スムーズに行うことができる.ありがとう!

    ポスト


    とにかく、最初からたじろぐのではなく、挑戦すればできるのです.私の话を振り返ってみると、プロジェクトを行う前に実力が足りなくてどうしよう.そう思うよしかし、最初のプロジェクトを行う過程で、私はだんだん自信を持って、2番目のプロジェクトを行う過程で、私は2つのAPIを利用して、2週間以内にユニットテストを完成しました.最初は無理だと思っていたが、諦めずにできることが勉強のきっかけになった.迫力のあるバックエンド開発者になることにずっと挑戦します.💡