def get_list(self, only_count=False, **kwargs): """ Pick 배너 리스트 """ pick_id = kwargs.get('pick_id') banners = PickBanner.objects.filter( pick=pick_id, is_display=True ).select_related('pick')\ .filter( pick__end_at__gte=(local_now().strftime('%Y%m%d%H%M%S')) ) if only_count: return banners.count() banners = banners.order_by('-banner_id') results = banners.all() if not results: return { 'list': [], } if not len(results): return { 'list': [], } return { 'list': results, }
def get_recommend_words(self, **kwargs): """ 추천 검색어 """ recommend_type = kwargs.get('type') placeholder = '{}_placeholder'.format(recommend_type) limit = kwargs.get('limit') now = local_now().strftime('%Y%m%d%H%M%S') words = RecommendWord.objects.filter(is_display=True) placeholder = words.filter( recommend_type=placeholder, start_date__lt=now, end_date__gt=now).values('contents').first() words = words.filter(recommend_type=recommend_type, start_date__lt=now, end_date__gt=now) words = words.values_list('contents', flat=True) words = words.order_by('?') words = words[:limit] res = dict() res['placeholder'] = placeholder.get( 'contents') if placeholder else None res['keywords'] = list(words) return res
def edit(self, request, pk=None): """ 제품 수정 요청 """ params = RequestForm(data=request.data) params.is_valid(raise_exception=True) user_id = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=user_id) product = get_object_or_404(Product, id=pk) contents = params.validated_data.get('contents') now = local_now().strftime('%Y%m%d%H%M%S') response = dict() try: RequestedEditProduct(contents=contents, product=product, user=user, create_date=now).save() response['is_success'] = True response['message'] = _("소중한 정보 감사합니다! 빠르게 수정하겠습니다:)") except: response['is_success'] = False response['message'] = _("요청 등록에 실패하였습니다.") return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED)
def join(self, request, pk=None): """ 이벤트 참여추가 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ cuid = int(request.META.get('HTTP_IDREGISTER') or 0) event = get_object_or_raise_404(Event, id=pk) user = get_object_or_raise_404(User, id=cuid) if EventParticipants.objects.filter(user=user, event=event).exists(): raise ConflictException(_("이미 이벤트에 참여하셨습니다.")) if user.review_count < event._condition: raise FailedPreconditionException( _("{} 개 이상의 리뷰를 작성한 회원만 참여할 수 있는 이벤트 입니다.\n" "회원님께서는 {} 개의 리뷰를 더 작성하셔야 합니다.".format( event._condition, event._condition - user.review_count))) response = dict() user_ip = get_client_ip(request) now = local_now().strftime('%Y%m%d%H%M%S') try: with transaction.atomic(): # RDS EventComment(event=event, user=user, comment="참가신청 완료", ip_address=user_ip, create_date=now).save() EventParticipants(user=user, event=event, create_date=now).save() _count = event.users.count() + 1 # dynamo DB aws_dynamodb_etc_list.update_events_comment( seq=event.seq, comment_count=_count) aws_dynamodb_event_participants.update_event(event_id=event.id, user_id=user.id, created_at=now) aws_dynamodb_events.update_event_comments_count( event_id=event.id, _count=_count) response['is_success'] = True response['message'] = _("이벤트에 참여되었습니다.") except: response['is_success'] = False response['message'] = _("등록에 실패하였습니다.") return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED)
def fetch(self, cursor): response = None if cursor == 1: response = { 'top_banners': Banner.objects.filter(banner_type='MAIN').order_by( 'seq', '?').all()[:20], 'weekly_rankings': { 'counted_at': iso8601(get_this_week(is_strformat=False)), 'categories': product_service.get_weekly_ranking() }, 'ongoing_events': { 'total_count': Event.objects.ongoing().filter(is_evaluated=True).count(), 'events': event_service.get_ongoing_evaluation_events(3) }, 'store_button': aws_dynamodb_etc_items.get_store_button(), 'paging': { 'next': 2 } } elif cursor == 2: this_month = local_now().strftime("%Y%m") new_products_count = Product.objects.new_products( this_month).count() if not new_products_count: this_month = (local_now() - relativedelta(months=1)).strftime("%Y%m") response = { 'recent_notice': Notice.objects.first(), 'new_products': { 'total_count': Product.objects.new_products(this_month).count(), 'items': product_service.get_new_products(this_month, 6) }, 'picks': Pick.objects.order_by('-seq').all()[:5], 'paging': { 'next': None } } return response
def ingredient(self, request, pk=None): """ 성분등록요청 --- 'file' 키값으로 이미지 파일 전송 <br><br> 헤더 <br> - IDREGISTER: (필수) 회원 항번 <br> """ user_id = request.META.get('HTTP_IDREGISTER') file_obj = request.FILES.get('file') user = get_object_or_404(User, id=user_id) product = get_object_or_404(Product, id=pk) now = local_now().strftime('%Y%m%d%H%M%S') response = dict() try: if file_obj: if RequestedIngredient.objects.filter( user=user, product=product).exists(): response['is_success'] = False response['message'] = _("이미 성분등록 요청을 하셨습니다.") return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED) requested_ingredient = RequestedIngredient(user=user, product=product, create_date=now) requested_ingredient.save() file_info = store_requested_ingredient_image( file_obj, requested_ingredient.id) if file_info: requested_ingredient.file_name_orig = file_info.get( 'file_org_name') requested_ingredient.file_name_save = file_info.get( 'file_save_name') requested_ingredient.file_dir = file_info.get('file_dir') requested_ingredient.file_size = file_info.get('file_size') requested_ingredient.file_type = file_info.get('file_type') requested_ingredient.save() response['is_success'] = True response['message'] = _("성분요청이 정상적으로 등록되었습니다.") else: response['is_success'] = False response['message'] = _("성분요청시 성분이미지는 필수 입니다.") except: response['is_success'] = False response['message'] = _("요청 등록에 실패하였습니다.") return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED)
def post(self, request, *args, **kwargs): """ 회원 아이디 값으로 인증하는 약식 로그인 api (안드로이드 용) --- - regid: (필수) push token 갱신용 파라미터 <br> <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> - UID: (필수) push token 갱신용 파라미터 <br> """ response = dict() try: cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = User.objects.get(id=cuid, is_active=True) except User.DoesNotExist: raise exceptions.NoUser except ValueError: raise exceptions.InvalidParameterException uuid = request.META.get('HTTP_UID') # 유효성 검사 params = AndroidLoginForm(data=request.data) params.is_valid(raise_exception=True) os_info = request.META.get('HTTP_OS') token = request.META.get('HTTP_TOKEN') if os_info == 'aos' and not token: token = params.validated_data.get('regid') if token != 'NO': if token and uuid: user.uuid = uuid if os_info == 'aos': user.regid = token elif os_info == 'ios': user.apns = token user.save() compair_push_token(platform=os_info, user_id=user.id, uuid=uuid, token=token) user.last_login = local_now() user.login_count = F('login_count') + 1 user.save() # 프로필 정보 response['user'] = UserLoginResponse(user).data return Response(response, status=status.HTTP_200_OK)
def get_list(self, **kwargs): limit = kwargs.get('limit', 20) cursor = kwargs.get('cursor') category_id = kwargs.get('category_id') base = Pick.objects.filter(category__is_display=True) cursor = int(cursor or 1) offset = (cursor - 1) * limit if category_id: base = base.filter(category=category_id) base = base.order_by('-seq') results = base.all()[offset:offset + limit + 1] if cursor != 1: categories = None else: c = PickCategory.objects.order_by('seq').values()[:15] total_new = False for item in c: date_days_ago = local_now() - timedelta(days=3) date_days_ago = date_days_ago.strftime('%Y%m%d%H%M%S') pick_last = Pick.objects.filter( category=item['category_id']).filter( _created_at__gte=date_days_ago) if pick_last: item['is_new'] = True total_new = True else: item['is_new'] = False categories = [{ 'category_id': 0, 'name': '전체 캐스트 보기', 'is_new': total_new }] categories += c next_offset = None if len(results) == limit + 1: results = list(results) next_offset = cursor + 1 del results[-1] return { 'picks': results, 'categories': categories, 'next_offset': next_offset, }
def wish(self, request, pk=None): """ 위시 확인 / 추가 / 삭제 --- - IDREGISTER: (필수) 회원 항번 <br> """ cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=cuid) product = get_object_or_404(Product, id=pk) response = dict() if request.method == 'GET': if Wish.objects.filter(user=user, product=product).exists(): response['is_success'] = False response['message'] = _("이미 위시리스트에 있습니다.") else: response['is_success'] = True response['message'] = _("위시리스트에 추가할 수 있습니다.") elif request.method == 'POST': if Wish.objects.filter(user=user, product=product).exists(): response['is_success'] = False response['message'] = _("이미 위시리스트에 있습니다.") else: try: now = local_now().strftime('%Y%m%d%H%M%S') Wish(user=user, product=product, create_date=now).save() response['is_success'] = True msg_arr = [ _("지름신 팍팍! 위시리스트 등록 완료"), _("코덕으로 가는 지름길! 위시리스트 등록 완료~") ] response['message'] = random.choice(msg_arr) except: response['is_success'] = False response['message'] = _("추가에 실패하였습니다.") elif request.method == 'DELETE': qs = Wish.objects.filter(user=user, product=product) if qs.exists(): qs.delete() response['is_success'] = True response['message'] = _("위시리스트가 삭제되었습니다.") else: response['is_success'] = False response['message'] = _("이미 삭제되었습니다.") return Response( SuccessMessageResponse(response).data, status=status.HTTP_200_OK )
def get_recommend_brands(self): """ 추천 브랜드 """ now = local_now().strftime('%Y%m%d%H%M%S') brands = Brand.objects.filter( is_display=True, is_recommended=True, start_date__lt=now, end_date__gt=now, ).order_by('seq', '?') return brands
def delete_tags(self, review_id): """ 태그와 리뷰와의 연결 제거 """ object_tags = TagObject.objects.select_related('tag').filter( type='review', object_id=review_id) now = local_now().strftime('%Y%m%d%H%M%S') # tag count update for _obj in object_tags: _obj.tag.count -= 1 _obj.tag.modified_date = now _obj.tag.save() # delete tag mapping if object_tags.exists(): object_tags.delete()
def make_like_message(self, instance): """ 좋아요 """ try: from django.utils import timezone review = Review.objects.select_related( 'user', 'product', 'product__brand' ).get( id=instance.reference_id ) two_week_ago = local_now() - datetime.timedelta(days=14) likes = Reviewlike.objects.select_related('register').filter( writer=review.user, product=review.product, create_date__gte=two_week_ago.strftime('%Y%m%d%H%M%S'), ) likes = likes.filter( create_date__gte=instance.created_at.astimezone( tz=timezone.get_current_timezone() ).strftime('%Y%m%d%H%M%S') ) likes = likes.values( # 'register__nickname', 'register__file_name_save', 'register__file_dir' ) first = list(likes)[-1] icon_image = "{}{}/{}".format( settings.CDN, first.get('register__file_dir'), first.get('register__file_name_save') ) path = os.path.splitext(icon_image) thumbnail = '%s_160%s' % (path[0], path[1]) return { 'message': instance.message, 'licon_image': thumbnail, 'ricon_image': review.product.product_image_160, 'target_url': "glowpick://glowpick.com?type=17&code={}".format(review.product_id), 'created_at': instance.updated_at if instance.updated_at else instance.created_at } except (Review.DoesNotExist, IndexError): return { 'message': instance.message }
def create(self, request, pick_id=None): """ 픽 (캐스트) 댓글 추가 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=cuid) pick = get_object_or_404(Pick, pick_id=pick_id) params = PickCommentForm(data=request.data) params.is_valid(raise_exception=True) if not (user.gender and user.skin_type and user.birth_year): raise InvalidParameterException( _("프로필 편집에서 추가정보를 입력하셔야 참여가 가능합니다.") ) response = dict() try: with transaction.atomic(): PickComment( pick=pick, user=user, comment=params.validated_data.get('comment'), ip_address=get_client_ip(request), create_date=local_now().strftime('%Y%m%d%H%M%S') ).save() # 픽상세 뷰용 업데이트 aws_dynamodb_pick.update_comment_count( pick_id=pick_id, comment_count=PickComment.objects.filter(pick=pick_id, is_display=True).count() + 1 ) response['is_success'] = True response['message'] = _("댓글 등록 완료!") except: response['is_success'] = False response['message'] = _("등록에 실패하였습니다.") return Response( SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED )
def new(self, request): """ 제품추가 등록요청 --- 'file' 키값으로 이미지 파일 전송 """ params = RequestForm(data=request.data) params.is_valid(raise_exception=True) user_id = request.META.get('HTTP_IDREGISTER') file_obj = request.FILES.get('file') contents = params.validated_data.get('contents') now = local_now().strftime('%Y%m%d%H%M%S') response = dict() try: requested_product = RequestedNewProduct(contents=contents, create_date=now) requested_product.user_id = int(user_id) if user_id else 1 requested_product.save() if file_obj: file_info = store_requested_product_image( file_obj, requested_product.id) if file_info: requested_product.file_name_orig = file_info.get( 'file_org_name') requested_product.file_name_save = file_info.get( 'file_save_name') requested_product.file_dir = file_info.get('file_dir') requested_product.file_size = file_info.get('file_size') requested_product.file_type = file_info.get('file_type') requested_product.save() response['is_success'] = True response['message'] = _("소중한 정보 감사합니다! 빠르게 등록하겠습니다:)") except: response['is_success'] = False response['message'] = _("요청 등록에 실패하였습니다.") return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED)
def create(self, request, pick_id): """픽 좋아요 등록""" response = {} cuid = int(request.META.get('HTTP_IDREGISTER') or 0) data = dict(user=cuid, create_date=local_now().strftime('%Y%m%d%H%M%S'), pick=pick_id) serializer = self.get_serializer(data=data) try: serializer.is_valid(raise_exception=True) except ValidationError as e: if 'non_field_errors' in e.detail: return Response({'is_success':False,'message':_("좋아요가 이미 있습니다.")},status=status.HTTP_409_CONFLICT) else: raise glow_exceptions.ServiceUnavailableException except Exception: raise glow_exceptions.ServiceUnavailableException try: with transaction.atomic(): self.perform_create(serializer) aws_dynamodb_pick.update_recommend_count( pick_id=pick_id, recommend_count=self.queryset.filter(pick=pick_id).count()+1 ) response['is_success'] = True response['message'] = _("좋아요 등록 완료!") except Exception: raise glow_exceptions.ServiceUnavailableException return Response( SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED )
def get_brand_banner(self, brand_id): """ 브랜드 배너 정보를 포함한 브랜드 정보 (facebook, twitter, youtube, homepage, ...) """ try: brand = Brand.objects.get(id=brand_id) except Brand.DoesNotExist: return None now = local_now().strftime('%Y%m%d%H%M%S') banners = Brandbanner.objects.filter( is_display=True, brand_id=brand_id, brand__start_date__lt=now, brand__end_date__gt=now, ) setattr(brand, 'banners', banners) if banners: setattr(brand, 'banner_ratio', 0.42) else: setattr(brand, 'banner_ratio', 0) return brand
def post(self, request, *args, **kwargs): """ 회원 로그인 --- - method: (필수) 로그인 방식 ( 'email', 'facebook', 'kakao' 중 하나) <br> - email: (옵션) email (회원 아이디 *method 가 email 일 경우 필수) <br> - password: (옵션) 비밀번호 (*method 가 email 일 경우 필수) <br> - uid: (필수) sns 인증 아이디 (*method 가 'facebook' or 'kakao' 일 경우 필수) <br> - regid: (안드로이드 필수) push token 갱신용 파라미터 <br> <br> <b>헤더</b> - UID: (필수) push token 갱신용 파라미터 <br> - TOKEN: (아이폰 필수) push token 갱신용 파라미터 <br> """ response = dict() # 유효성 검사 params = SignInForm(data=request.data) params.is_valid(raise_exception=True) method = params.validated_data.get('method') uid = params.validated_data.get('uid') uuid = request.META.get('HTTP_UID') os_info = request.META.get('HTTP_OS') token = request.META.get('HTTP_TOKEN') if os_info == 'aos' and not token: token = params.validated_data.get('regid') # 인증 if method == 'facebook': provider = FacebookProvider(request) try: sociallogin = SocialAccount.objects.get(provider=provider.id, uid=uid) except SocialAccount.DoesNotExist: raise exceptions.NoSocialLogin try: user = User.objects.get(id=sociallogin.user_id) except User.DoesNotExist: raise exceptions.NoEmail elif method == 'kakao': provider = KakaoProvider(request) try: sociallogin = SocialAccount.objects.get(provider=provider.id, uid=uid) except SocialAccount.DoesNotExist: raise exceptions.NoSocialLogin try: user = User.objects.get(id=sociallogin.user_id) except User.DoesNotExist: raise exceptions.NoEmail else: user = custom_auth.authenticate( email=params.data.get('email'), password=params.data.get('password')) if user is None: raise exceptions.NoEmail elif not user.is_active: raise exceptions.IsInactiveUser # push 토큰 업데이트 if token != 'NO': if token and uuid: user.uuid = uuid if os_info == 'aos': user.regid = token elif os_info == 'ios': user.apns = token user.save() compair_push_token(platform=os_info, user_id=user.id, uuid=uuid, token=token) user.last_login = local_now() user.login_count = F('login_count') + 1 user.save() # 프로필 정보 response['user'] = UserLoginResponse(user).data return Response(response, status=status.HTTP_200_OK)
def post(self, request): """ 회원 가입 --- - method: (필수) 로그인 방식 ( 'email', 'facebook', 'kakao' 중 하나) <br> - email: (필수) email <br> - password: (필수) 비밀번호 <br> - uid: (옵션) sns 인증 아이디 (*method 가 'facebook' or 'kakao' 일 경우 필수) <br> - image_url: (옵션) sns 추가 정보 <br> - regid: (안드로이드 필수) push token 갱신용 파라미터 <br> <br> <b>헤더</b> - UID: (필수) push token 갱신용 파라미터 <br> - TOKEN: (아이폰 필수) push token 갱신용 파라미터 <br> """ response = dict() # 유효성 검사 form = SignUpForm(data=request.data) form.is_valid(raise_exception=True) method = form.validated_data.get('method') uid = form.validated_data.get('uid') image_url = form.validated_data.get('image_url') uuid = request.META.get('HTTP_UID') os_info = request.META.get('HTTP_OS') token = request.META.get('HTTP_TOKEN') if os_info == 'aos' and not token: token = form.validated_data.get('regid') # 새 계정 instance 생성 user = User.objects.create_user( username=form.validated_data.get('email'), password=form.validated_data.get('password'), nickname=form.validated_data.get('nickname').strip(), date_joined=local_now(), ip_address=get_client_ip(request), uuid=uuid, last_login=local_now(), ) token_dict = {'aos': 'regid', 'ios': 'apns'} if token_dict.get(os_info) and token != 'NO': setattr(user, token_dict.get(os_info), token) user.save() # SNS 정보가 있다면 allauth socialaccount instance 생성 if method == 'facebook': provider = FacebookProvider(request) if not SocialAccount.objects.filter( user=user, provider=provider.id, uid=uid): SocialAccount(user=user, provider=provider.id, uid=uid, extra_data={}).save() elif method == 'kakao': provider = KakaoProvider(request) if not SocialAccount.objects.filter( user=user, provider=provider.id, uid=uid): SocialAccount(user=user, provider=provider.id, uid=uid, extra_data={}).save() # SNS extra_data 를 가지고 user field 갱신 if image_url: file_info = edit_profile_image_by_url(image_url, user.id) if file_info: user.file_name_orig = file_info.get('file_org_name') user.file_name_save = file_info.get('file_save_name') user.file_dir = file_info.get('file_dir') user.file_size = file_info.get('file_size') user.file_type = file_info.get('file_type') user.save() # push 토큰 업데이트 if token != 'NO': if token and uuid: compair_push_token(platform=os_info, user_id=user.id, uuid=uuid, token=token) # 알림함 메세지 생성 try: MessageBox(user_id=user.id, category=MessageCategory.objects.get(name='가입완료'), message='반갑습니다! 글로우픽 사용이 처음이라면 꼭 확인해주세요:)').save() except: pass # 프로필 정보 response['user'] = UserLoginResponse(user).data return Response(response, status=status.HTTP_201_CREATED)
def create(self, request, event_id=None): """ 이벤트 댓글 추가 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ cuid = int(request.META.get('HTTP_IDREGISTER') or 0) params = EventCommentForm(data=request.data) params.is_valid(raise_exception=True) comment = params.validated_data.get('comment') event = get_object_or_raise_404(Event, id=event_id) user = get_object_or_raise_404(User, id=cuid) if EventComment.objects.filter(user=user, event=event).exists(): raise ConflictException(_("이미 이벤트에 참여하셨습니다.")) if user.review_count < event._condition: raise FailedPreconditionException( _("{} 개 이상의 리뷰를 작성한 회원만 참여할 수 있는 이벤트 입니다.\n" "회원님께서는 {} 개의 리뷰를 더 작성하셔야 합니다.".format( event._condition, event._condition - user.review_count))) response = dict() user_ip = get_client_ip(request) now = local_now().strftime('%Y%m%d%H%M%S') try: with transaction.atomic(): # RDS EventComment(event=event, user=user, comment=comment, ip_address=user_ip, create_date=now).save() _count = event.users.count() + 1 # dynamo DB aws_dynamodb_etc_list.update_events_comment( seq=event.seq, comment_count=_count) aws_dynamodb_event_participants.update_event(event_id=event.id, user_id=user.id, created_at=now) aws_dynamodb_events.update_event_comments_count( event_id=event.id, _count=_count) response['is_success'] = True response['message'] = _("당첨을 기다리며, 지금 등록되어 있는 \n" "연락처와 주소를 한 번 더 확인해주세요!") if user.zipcode: response['user_address'] = _( "연락처 : {}\n" "주소 : ({}) {} {}".format(user.tel, user.zipcode, user.address, user.address_more)) else: response['user_address'] = _("연락처 : {}\n" "주소 : {} {}".format( user.tel, user.address, user.address_more)) except: response['is_success'] = False response['message'] = _("등록에 실패하였습니다.") return Response(EventCommentJoin(response).data, status=status.HTTP_201_CREATED)
def destroy(self, request, pk=None): """ 리뷰 삭제 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=cuid) try: review_service.reset_rank(cuid) review = get_object_or_404(Review, id=pk, user=user, is_display=True) product = review.product with transaction.atomic(): # 해당 리뷰에 블라인드 사유 삭제 BlindedReview.objects.filter(review_id=pk).delete() # 좋아요 삭제 Reviewlike.objects.filter(writer=user, product=product).delete() # 좋아요 알림 메세지 삭제 MessageBox.objects.filter( user=user, category=MessageCategory.objects.get(name='좋아요'), reference_id=review.id ).update(is_active=False) # review delete review.delete() # user info update user.review_count -= 1 user.score -= 1 user.save() # product info update update_product_info.delay(product.id) # tag update object_tags = TagObject.objects.filter(type='review', object_id=pk) now = local_now().strftime('%Y%m%d%H%M%S') # tag count update for _obj in object_tags: _obj.tag.count -= 1 _obj.tag.modified_date = now _obj.tag.save() # delete tag mapping if object_tags.exists(): object_tags.delete() # elastic delete elasticsearch_reviews.delete(_id=pk) # 레디스와 연동하기 # 처음 리뷰 찾기 first_review = Review_first_log.objects.filter( id=product.id, user=user).all()[:1] is_first = len(first_review) > 0 # 리뷰 포인트 가져오기 review_points = review_service.get_review_points() user_review_count = review_service.get_review_count(user.id) this_week_user_review_count = \ review_service.get_this_week_review_count(user.id) score = review_points['review_point'] + \ ((user_review_count % 3 == 0) * \ review_points['multiple_bonus_point']) + \ (is_first * review_points['first_bonus_point']) # 처음 기존 리뷰 삭제 if is_first is True: first_review[0].delete() # 처음 리뷰 검색후 넣어주기 new_first_reviews = Review.objects.filter( product=product).order_by('_created_at').all()[:2] # 최초 하나는 내 리뷰임으로 두번째 것을 넣어준다. if len(new_first_reviews) > 1: # 넣어준다 Review_first_log( id=product.id, user=new_first_reviews[1].user, timestamp=new_first_reviews[1]._created_at).save() # 레디스는 automic 이 적용되지 않음으로 rdb 에서 동작을 마무리한 후 redis 에 # 적용한다. # 삭제로 리뷰가 0개가 되는 순간 배치에서 감지하지 않음으로 주의해야 한다. # 레디스에 스코어 값 감소시키기 # 리뷰가 정상이면 if review.state == "N" and review.when_seceded == 0 and review.is_display == True and review.user.is_active == 1 and review.user.is_blinded == 0 and review.user.is_black == 0 : # 리뷰가 마지막이었다면 if user_review_count == 1: # rank 에서 삭제 period_zrem('all', user.id) else: # 아니면 감소 period_zincrby('all', user.id, -score) # review 에 _created_at 은 kst 가 기준이기 떄문에 kst 로 비교한다 if iso8601(datetime.strptime( review._created_at, "%Y%m%d%H%M%S")) > \ iso8601(kst_last_week_friday_18_00()): # 이번주 리뷰가 마지막이었다면 if this_week_user_review_count == 1: # 삭제한다 period_zrem('this_week', user.id) else: # 아니면 감소 period_zincrby('this_week', user.id, -score) # 처음 리뷰가 맞고 다른 사람이 쓴 것이 있으면 if is_first is True and len(new_first_reviews) > 1: # 처음 리뷰로 등록된 유저 보너스 점수 레디스에 등록하기 period_zincrby('all', new_first_reviews[1].user.id, review_points['first_bonus_point']) if review._created_at > \ iso8601(kst_last_week_friday_18_00()): period_zincrby('this_week', new_first_reviews[1].user.id, review_points['first_bonus_point']) except: raise return Response({}, status=status.HTTP_200_OK)
def update(self, request, pk=None): """ 리뷰 수정 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ # parameters cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=cuid) params = ReviewUpdateForm(data=request.data) params.is_valid(raise_exception=True) client_ip = get_client_ip(request) contents = params.validated_data.get('contents') new_rating = params.validated_data.get('rating') review = get_object_or_404(Review, id=pk, user=user, is_display=True) product = review.product with transaction.atomic(): # review update # 블라인드 상태인 리뷰는 사용자가 수정시 검수중 상태로 변경된다. if review.state == 'B': review.state = 'C' review.ip_address = client_ip if contents: review.contents = contents if new_rating: review.rating = new_rating review.save() # product info update update_product_info.delay(product.id) # tag update tags = extract_tags(contents) now = local_now().strftime('%Y%m%d%H%M%S') object_tags = TagObject.objects.filter(type='review', object_id=review.id) # tag count update for _obj in object_tags: _obj.tag.count -= 1 _obj.tag.modified_date = now _obj.tag.save() # delete tag mapping if object_tags.exists(): object_tags.delete() for tag_name in tags: tag, created = Tag.objects.get_or_create(name=tag_name) if created: TagObject(type='review', object_id=review.id, tag=tag).save() tag.create_date = now tag.save() else: if not TagObject.objects.filter(type='review', object_id=review.id, tag=tag).exists(): TagObject(type='review', object_id=review.id, tag=tag).save() tag.count += 1 tag.modified_date = now tag.save() review.tag = ",".join(tags) # review update review.save() # elastic update body = { "doc": {'rating': new_rating, 'reviewText': contents, 'tag': ",".join(tags)} } elasticsearch_reviews.update(_id=review.id, body=body) return Response({}, status=status.HTTP_200_OK)
def create(self, request): """ 새 리뷰 작성 --- <br> <b>헤더</b> - IDREGISTER: (필수) 회원 항번 <br> """ # parameters cuid = int(request.META.get('HTTP_IDREGISTER') or 0) user = get_object_or_404(User, id=cuid) review_service.reset_rank(cuid) params = ReviewWriteForm(data=request.data) params.is_valid(raise_exception=True) if user.gender is None or user.skin_type is None or user.birth_year is None: raise InvalidParameterException( _("내정보에서 추가정보를 입력하셔야 작성이 가능합니다.") ) client_ip = get_client_ip(request) contents = params.validated_data.get('contents') rating = params.validated_data.get('rating') product_id = params.validated_data.get('product_id') product = get_object_or_404(Product, id=product_id, is_display=True) if Review.objects.filter(user=cuid, product=product_id).exists(): raise ConflictException( _("이미 리뷰를 작성한 제품입니다.") ) with transaction.atomic(): # review insert now = local_now().strftime('%Y%m%d%H%M%S') review = Review(user=user, product=product, rating=rating, contents=contents, ip_address=client_ip, is_display=True, is_evaluation=False, _created_at=now) # 평가단 여부 확인 if EventPrizeMapping.objects.filter( user=user, product=product ).filter( event__activity_date__gte=local_now().strftime('%Y%m%d%H%M%S') ).exists(): review.is_evaluation = True review.save() # user info update user.review_count += 1 user.score += 1 user.save() # product info update update_product_info.delay(product_id) # tag update tags = extract_tags(contents) for tag_name in tags: tag, created = Tag.objects.get_or_create(name=tag_name) if created: TagObject(type='review', object_id=review.id, tag=tag).save() tag.create_date = now tag.save() else: if not TagObject.objects.filter(type='review', object_id=review.id, tag=tag).exists(): TagObject(type='review', object_id=review.id, tag=tag).save() tag.count += 1 tag.modified_date = now tag.save() review.tag = ",".join(tags) review.save() # elastic update body = dict() # review body['idreviewcomment'] = review.id body['reviewText'] = contents body['rating'] = rating body['likeCount'] = 0 body['isDisplay'] = 1 body['isEvaluation'] = 0 body['create_date'] = now body['tag'] = ",".join(tags) # user body['idRegister'] = user.id body['nickName'] = user.nickname body['birthYear'] = user.birth_year body['skinType'] = user._skin_type body['gender'] = user._gender body['registerScore'] = user.score body['registerRank'] = user.rank body['isBlind'] = user.is_blinded body['registerFileDir'] = user.file_dir body['registerFileSaveName'] = user.file_name_save # product body['idProduct'] = product.id body['productTitle'] = product.name body['idBrand'] = product.brand_id body['productFileDir'] = product.file_dir body['productFileSaveName'] = product.file_name body['brandTitle'] = product.brand.name body['productIsDisplay'] = int(product.is_display) categories = product.categories.all().values('id', 'main_category_id') body['firstCategoryList'] = "" body['secondCategoryList'] = "" for category in categories: body['firstCategoryList'] += "[" + str(category['main_category_id']) + "]" body['secondCategoryList'] += "[" + str(category['id']) + "]" try: goods_info = ProductGoods.objects.get(product_id=product_id, goods_count__gt=0) body['goods_info'] = { "goods_count": goods_info.goods_count, "min_price": goods_info.min_price, "max_price": goods_info.max_price } except ProductGoods.DoesNotExist: pass elasticsearch_reviews.add(body=body, _id=review.id) is_first = not Review.objects.filter(product=product_id).exists() response = dict() response['review_count'] = user.review_set.count() # redis 에 update 하는 쿼리 # 첫 번째 리뷰인지 확인한다. # 첫 리뷰시에 첫 리뷰 관리 테이블에 넣는다. if (is_first): try: Review_first_log(id=product_id, user=user, timestamp=kst_now().strftime("%Y%m%d%H%M%S") ).save(force_insert=True) except IntegrityError : # 테이블에 접근하는 순간 이미 product 가 존재해서 에러를 띄운다면 처음이 아님으로 is_first 를 False 로 변경한다. is_first = False review_create_cash = { 'is_first':is_first, 'written':True } # review count 에서 사용할 수 있도록 redis 에 set 해준다. set_review_is_written(user.id,review_create_cash) return Response(ReviewWriteResponse(response).data, status=status.HTTP_201_CREATED)