セカンダリプリフェッチクローンプロジェクト
紹介する
Prepは、ナビゲーションから支払い、参加するアクティビティ、1日のカテゴリ、ソーシャルクラブ、旅行製品をWebサイトとアプリケーションを通じて提供します.
チーム要素の概要
チームメンバー:フロント2名、バックエンド3名
チーム名:梗-移動バージョン
モデリング
実装機能
User app
Review app
Product app
私が実施した機能🎉
今回、チームメンバーは多くの譲歩を行い、2つのapiを使用してコメントとソーシャルログインを実現しました.
KakaoSocialログイン
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)
コメント機能
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週間以内にユニットテストを完成しました.最初は無理だと思っていたが、諦めずにできることが勉強のきっかけになった.迫力のあるバックエンド開発者になることにずっと挑戦します.💡
Reference
この問題について(セカンダリプリフェッチクローンプロジェクト), 我々は、より多くの情報をここで見つけました https://velog.io/@sjwm98/2차-프립-클론프로젝트テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol