From c59360568e97f46f1b78526af381ca0b5a016156 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Fri, 2 Aug 2024 15:50:15 +0900 Subject: [PATCH 01/22] =?UTF-8?q?feat:=20admin=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=20=EB=A0=88=EC=8A=A4=ED=86=A0=EB=9E=91=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restaurants/admin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/restaurants/admin.py b/restaurants/admin.py index 4185d36..069ce1a 100644 --- a/restaurants/admin.py +++ b/restaurants/admin.py @@ -1,3 +1,4 @@ -# from django.contrib import admin +from django.contrib import admin +from .models import Restaurant -# Register your models here. +admin.site.register(Restaurant) From 67b8d84f213245d3d49774c7313790443f025fb5 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Fri, 2 Aug 2024 16:05:54 +0900 Subject: [PATCH 02/22] =?UTF-8?q?feat:=20admin=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=20friends=20=EB=AA=A8=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/admin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/friends/admin.py b/friends/admin.py index 4185d36..72ba356 100644 --- a/friends/admin.py +++ b/friends/admin.py @@ -1,3 +1,4 @@ -# from django.contrib import admin +from django.contrib import admin +from .models import Friend -# Register your models here. +admin.site.register(Friend) From d64938c56b9f2d76813d6a1cdad73a4bd125fb21 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:07:02 +0900 Subject: [PATCH 03/22] =?UTF-8?q?chore:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/admin.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/accounts/admin.py b/accounts/admin.py index c4a654c..8f8ef1f 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -1,4 +1,18 @@ from django.contrib import admin +from django.contrib.auth.admin import UserAdmin from .models import User -admin.site.register(User) + +class CustomUserAdmin(UserAdmin): + list_display = ( + "id", + "name", + "email", + "profile_img", + "reliability", + "date_joined", + "last_login", + ) + + +admin.site.register(User, CustomUserAdmin) From 90981f3e7276e7e09ecfc7a1fd488ceb51bc0300 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:12:29 +0900 Subject: [PATCH 04/22] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD/=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/admin.py | 14 ++- .../0005_remove_friend_state_friendrequest.py | 61 +++++++++++++ ..._friend_state_friend_unique_user_friend.py | 22 +++++ friends/migrations/0007_friend_created_at.py | 21 +++++ friends/models.py | 10 ++- friends/serializers.py | 6 ++ friends/urls.py | 2 + friends/views.py | 88 +++++++++++++++++++ 8 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 friends/migrations/0005_remove_friend_state_friendrequest.py create mode 100644 friends/migrations/0006_remove_friend_state_friend_unique_user_friend.py create mode 100644 friends/migrations/0007_friend_created_at.py diff --git a/friends/admin.py b/friends/admin.py index 72ba356..7156a9b 100644 --- a/friends/admin.py +++ b/friends/admin.py @@ -1,4 +1,14 @@ from django.contrib import admin -from .models import Friend +from .models import Friend, FriendRequest -admin.site.register(Friend) + +class FriendAdmin(admin.ModelAdmin): + list_display = ("id", "user", "friend", "created_at") + + +class FriendRequestAdmin(admin.ModelAdmin): + list_display = ("id", "from_user", "to_user", "state", "created_at") + + +admin.site.register(Friend, FriendAdmin) +admin.site.register(FriendRequest, FriendRequestAdmin) diff --git a/friends/migrations/0005_remove_friend_state_friendrequest.py b/friends/migrations/0005_remove_friend_state_friendrequest.py new file mode 100644 index 0000000..9475730 --- /dev/null +++ b/friends/migrations/0005_remove_friend_state_friendrequest.py @@ -0,0 +1,61 @@ +# Generated by Django 4.2.14 on 2024-08-04 16:07 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("friends", "0004_merge_20240801_0544"), + ] + + operations = [ + migrations.CreateModel( + name="FriendRequest", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "state", + models.CharField( + choices=[ + ("pending", "Pending"), + ("accepted", "Accepted"), + ("declined", "Declined"), + ], + default="pending", + max_length=20, + ), + ), + ( + "from_user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="sent_friend_requests", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "to_user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="received_friend_requests", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "unique_together": {("from_user", "to_user")}, + }, + ), + ] diff --git a/friends/migrations/0006_remove_friend_state_friend_unique_user_friend.py b/friends/migrations/0006_remove_friend_state_friend_unique_user_friend.py new file mode 100644 index 0000000..35d787c --- /dev/null +++ b/friends/migrations/0006_remove_friend_state_friend_unique_user_friend.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.14 on 2024-08-04 16:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("friends", "0005_remove_friend_state_friendrequest"), + ] + + operations = [ + migrations.RemoveField( + model_name="friend", + name="state", + ), + migrations.AddConstraint( + model_name="friend", + constraint=models.UniqueConstraint( + fields=("user", "friend"), name="unique_user_friend" + ), + ), + ] diff --git a/friends/migrations/0007_friend_created_at.py b/friends/migrations/0007_friend_created_at.py new file mode 100644 index 0000000..e844524 --- /dev/null +++ b/friends/migrations/0007_friend_created_at.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.14 on 2024-08-04 16:50 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + dependencies = [ + ("friends", "0006_remove_friend_state_friend_unique_user_friend"), + ] + + operations = [ + migrations.AddField( + model_name="friend", + name="created_at", + field=models.DateTimeField( + auto_now_add=True, default=django.utils.timezone.now + ), + preserve_default=False, + ), + ] diff --git a/friends/models.py b/friends/models.py index 15c93ae..41e315d 100644 --- a/friends/models.py +++ b/friends/models.py @@ -7,11 +7,17 @@ class Friend(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="friends") friend = models.ForeignKey(User, on_delete=models.CASCADE, related_name="friend_of") + created_at = models.DateTimeField(auto_now_add=True) class Meta: - unique_together = ("user", "friend") + constraints = [ + models.UniqueConstraint( + fields=["user", "friend"], name="unique_user_friend" + ) + ] +# 친구 신청 모델 class FriendRequest(models.Model): STATE_CHOICES = [ ("pending", "Pending"), @@ -26,7 +32,7 @@ class FriendRequest(models.Model): User, on_delete=models.CASCADE, related_name="received_friend_requests" ) created_at = models.DateTimeField(auto_now_add=True) - state = models.CharField(max_length=20, choices=STATE_CHOICES, default="request") + state = models.CharField(max_length=20, choices=STATE_CHOICES, default="pending") class Meta: unique_together = ("from_user", "to_user") diff --git a/friends/serializers.py b/friends/serializers.py index 13aee59..4c9c395 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -132,6 +132,12 @@ def get_rating_average(self, obj): return obj.rating_average() +class FriendRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Friend + fields = "__all__" + + class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() diff --git a/friends/urls.py b/friends/urls.py index efafd47..7768f62 100644 --- a/friends/urls.py +++ b/friends/urls.py @@ -9,4 +9,6 @@ ), path("friends/", views.friend_list, name="friend-list"), path("friend-recommend/", views.friend_recommend, name="friend-recommend"), + # 추가 기능을 테스트하기 위한 url으로 실제로는 /friend 안에서 모두 진행됨 + path("friend-request/", views.FriendRequestView.as_view(), name="friend-request"), ] diff --git a/friends/views.py b/friends/views.py index 39406c6..0fde537 100644 --- a/friends/views.py +++ b/friends/views.py @@ -1,5 +1,9 @@ # from django.shortcuts import render from rest_framework.decorators import api_view +from rest_framework.views import APIView + +# from rest_framework.authentication import TokenAuthentication +# from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework import status @@ -16,6 +20,12 @@ from django.views.decorators.csrf import csrf_exempt from django.db.models import Count, Q import random +from .serializers import RestaurantSerializer + +# from .serializers import FriendSerializer, FriendRequestSerializer +from accounts.models import User + +from django.shortcuts import get_object_or_404 @api_view(["GET"]) @@ -128,3 +138,81 @@ def friend_recommend(request): except User.DoesNotExist: return Response({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND) +# 친구신청 +class FriendRequestView(APIView): + # authentication_classes = [TokenAuthentication] + # permission_classes = [IsAuthenticated] + + def post(self, request): + action = request.data.get("action") + friend_id = request.data.get("friend_id") + + if action == "send": + return self.send_request(request, friend_id) + elif action == "accept": + return self.accept_request(request, friend_id) + elif action == "decline": + return self.decline_request(request, friend_id) + else: + return Response( + {"message": "올바르지 않은 요청입니다."}, status=status.HTTP_400_BAD_REQUEST + ) + + # 친구 요청 + def send_request(self, request, friend_id): + to_user = get_object_or_404(User, id=friend_id) + from_user = request.user + + if FriendRequest.objects.filter(from_user=from_user, to_user=to_user).exists(): + return Response( + {"message": "이미 친구 요청을 보냈습니다."}, status=status.HTTP_400_BAD_REQUEST + ) + + friend_request = FriendRequest( + from_user=from_user, to_user=to_user, state="pending" + ) + friend_request.save() + + return Response({"message": "친구 요청을 보냈습니다."}, status=status.HTTP_201_CREATED) + + # 친구 수락 + def accept_request(self, request, friend_id): + # 친구 요청을 보낸 사용자의 id와 일치하는 요청이 있는지 확인 + friend_request = get_object_or_404(FriendRequest, from_user__id=friend_id) + + if friend_request.to_user != request.user: + return Response({"message": "권한이 없습니다."}, status=status.HTTP_403_FORBIDDEN) + if friend_request.state != "pending": + return Response( + {"message": "이미 처리된 요청입니다."}, status=status.HTTP_400_BAD_REQUEST + ) + + friend_request.state = "accepted" + friend_request.save() + + # 양방향 친구 관계 설정 + from_user = friend_request.from_user + to_user = friend_request.to_user + + friend_relation = Friend.objects.create(user=from_user, friend=to_user) + friend_relation.save() + reverse_friend_relation = Friend.objects.create(user=to_user, friend=from_user) + reverse_friend_relation.save() + + return Response({"message": "친구 신청을 수락했습니다."}, status=status.HTTP_200_OK) + + # 친구 거절 + def decline_request(self, request, friend_id): + friend_request = get_object_or_404(FriendRequest, from_user__id=friend_id) + + if friend_request.to_user != request.user: + return Response({"message": "권한이 없습니다."}, status=status.HTTP_403_FORBIDDEN) + if friend_request.state != "pending": + return Response( + {"message": "이미 처리된 요청입니다."}, status=status.HTTP_400_BAD_REQUEST + ) + + friend_request.state = "declined" + friend_request.save() + + return Response({"message": "친구 신청을 거절했습니다."}, status=status.HTTP_200_OK) From 3e7e4a5306e2edb2d25c010a9aa05587c9011fec Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:17:36 +0900 Subject: [PATCH 05/22] =?UTF-8?q?chore:=20=EB=A7=88=EC=9D=B4=EA=B7=B8?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=EC=88=98=EC=A0=95=20id=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=ED=95=98=EB=A0=A4?= =?UTF-8?q?=EA=B3=A0=20=ED=96=88=EB=8D=98=EB=93=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/migrations/0005_alter_user_id.py | 17 +++++++++++++++++ accounts/migrations/0006_alter_user_id.py | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 accounts/migrations/0005_alter_user_id.py create mode 100644 accounts/migrations/0006_alter_user_id.py diff --git a/accounts/migrations/0005_alter_user_id.py b/accounts/migrations/0005_alter_user_id.py new file mode 100644 index 0000000..a2ebe9b --- /dev/null +++ b/accounts/migrations/0005_alter_user_id.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.14 on 2024-08-02 18:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0004_remove_user_profile_pic_user_profile_img"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="id", + field=models.AutoField(primary_key=True, serialize=False), + ), + ] diff --git a/accounts/migrations/0006_alter_user_id.py b/accounts/migrations/0006_alter_user_id.py new file mode 100644 index 0000000..fc62ce3 --- /dev/null +++ b/accounts/migrations/0006_alter_user_id.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.14 on 2024-08-02 18:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("accounts", "0005_alter_user_id"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="id", + field=models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ] From 08df7f4dac06cd7d6436f0e45d6ff5559265b527 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:25:15 +0900 Subject: [PATCH 06/22] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 124 ++++++++++++++++++++++++++++++++++++++++- friends/urls.py | 2 + friends/views.py | 5 +- 3 files changed, 127 insertions(+), 4 deletions(-) diff --git a/friends/serializers.py b/friends/serializers.py index 4c9c395..2569a85 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -132,10 +132,132 @@ def get_rating_average(self, obj): return obj.rating_average() +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = ["id", "name", "profile_img", "reliability"] + + class FriendRequestSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="from_user.id") + name = serializers.CharField(source="from_user.name") + profile_img = serializers.URLField(source="from_user.profile_img.url") + reliability = serializers.IntegerField(source="from_user.reliability") + common_restaurant_count = serializers.SerializerMethodField() + + class Meta: + model = FriendRequest + fields = [ + "id", + "name", + "profile_img", + "reliability", + "common_restaurant_count", + ] + + def get_common_restaurant_count(self, obj): + try: + user = obj.from_user + # friend_user = self.context.get('request').user + friend_user = User.objects.get(id=21) + + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = set( + UserRestaurantsList.objects.filter(user=friend_user).values_list( + "restaurant_id", flat=True + ) + ) + return len(user_restaurants.intersection(friend_restaurants)) + except User.DoesNotExist: + return 0 + + +class FriendRecommendSerializer(serializers.ModelSerializer): + common_restaurant_count = serializers.SerializerMethodField() + common_restaurants = serializers.SerializerMethodField() + + class Meta: + model = User + fields = [ + "id", + "name", + "profile_img", + "reliability", + "common_restaurant_count", + "common_restaurants", + ] + + def get_common_restaurant_count(self, obj): + user = self.context.get("user") + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = set( + UserRestaurantsList.objects.filter(user=obj).values_list( + "restaurant_id", flat=True + ) + ) + return len(user_restaurants.intersection(friend_restaurants)) + + def get_common_restaurants(self, obj): + user = self.context.get("user") + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = UserRestaurantsList.objects.filter( + user=obj, restaurant_id__in=user_restaurants + ).values("restaurant__name", "restaurant__image_url")[:2] + return friend_restaurants + + def to_representation(self, instance): + representation = super().to_representation(instance) + include_restaurants = self.context.get("include_restaurants", False) + if not include_restaurants: + representation.pop("common_restaurants") + return representation + + +class FriendSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="friend.id") + name = serializers.CharField(source="friend.name") + profile_img = serializers.URLField(source="friend.profile_img.url") + reliability = serializers.IntegerField(source="friend.reliability") + class Meta: model = Friend - fields = "__all__" + fields = [ + "id", + "name", + "profile_img", + "reliability", + ] + + +class RestaurantlistSerializer(serializers.ModelSerializer): + rating_average = serializers.SerializerMethodField() + + class Meta: + model = Restaurant + fields = [ + "id", + "name", + "food_type", + "rating_average", + "latitude", + "longitude", + "image_url", + ] + + def get_rating_average(self, obj): + return obj.rating_average() class RestaurantSerializer(serializers.ModelSerializer): diff --git a/friends/urls.py b/friends/urls.py index 7768f62..979cad6 100644 --- a/friends/urls.py +++ b/friends/urls.py @@ -11,4 +11,6 @@ path("friend-recommend/", views.friend_recommend, name="friend-recommend"), # 추가 기능을 테스트하기 위한 url으로 실제로는 /friend 안에서 모두 진행됨 path("friend-request/", views.FriendRequestView.as_view(), name="friend-request"), + path("friends/", views.friend_list, name="friend-list"), + path("friend-recommend/", views.friend_recommend, name="friend-recommend"), ] diff --git a/friends/views.py b/friends/views.py index 0fde537..a662319 100644 --- a/friends/views.py +++ b/friends/views.py @@ -22,9 +22,6 @@ import random from .serializers import RestaurantSerializer -# from .serializers import FriendSerializer, FriendRequestSerializer -from accounts.models import User - from django.shortcuts import get_object_or_404 @@ -138,6 +135,8 @@ def friend_recommend(request): except User.DoesNotExist: return Response({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND) + + # 친구신청 class FriendRequestView(APIView): # authentication_classes = [TokenAuthentication] From 90344e88753d2527f6018d28ad5e9cdddcd53559 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Fri, 2 Aug 2024 01:10:12 +0900 Subject: [PATCH 07/22] =?UTF-8?q?fix:=20=EC=8A=88=ED=8D=BC=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EC=96=B4=EB=93=9C=EB=AF=BC=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/admin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/accounts/admin.py b/accounts/admin.py index 8f8ef1f..45aab7a 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -16,3 +16,6 @@ class CustomUserAdmin(UserAdmin): admin.site.register(User, CustomUserAdmin) +from .models import User + +admin.site.register(User) From c56be2d260bc2d1db9072705736266648a449458 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Fri, 2 Aug 2024 16:05:54 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feat:=20admin=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=20friends=20=EB=AA=A8=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/admin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/friends/admin.py b/friends/admin.py index 7156a9b..6ab74c3 100644 --- a/friends/admin.py +++ b/friends/admin.py @@ -12,3 +12,6 @@ class FriendRequestAdmin(admin.ModelAdmin): admin.site.register(Friend, FriendAdmin) admin.site.register(FriendRequest, FriendRequestAdmin) +from .models import Friend + +admin.site.register(Friend) From 6eb0da98e83de15b8815e7a4f7f843ecd39b51ff Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:07:02 +0900 Subject: [PATCH 09/22] =?UTF-8?q?chore:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/admin.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/accounts/admin.py b/accounts/admin.py index 45aab7a..0603e0c 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -14,8 +14,4 @@ class CustomUserAdmin(UserAdmin): "last_login", ) - admin.site.register(User, CustomUserAdmin) -from .models import User - -admin.site.register(User) From 1ca6f0f5a13557f973c36c488798e83884c9798a Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:12:29 +0900 Subject: [PATCH 10/22] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD/=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/admin.py | 3 --- friends/serializers.py | 6 ++++++ friends/urls.py | 2 -- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/friends/admin.py b/friends/admin.py index 6ab74c3..7156a9b 100644 --- a/friends/admin.py +++ b/friends/admin.py @@ -12,6 +12,3 @@ class FriendRequestAdmin(admin.ModelAdmin): admin.site.register(Friend, FriendAdmin) admin.site.register(FriendRequest, FriendRequestAdmin) -from .models import Friend - -admin.site.register(Friend) diff --git a/friends/serializers.py b/friends/serializers.py index 2569a85..10a5f81 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -260,6 +260,12 @@ def get_rating_average(self, obj): return obj.rating_average() +class FriendRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Friend + fields = "__all__" + + class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() diff --git a/friends/urls.py b/friends/urls.py index 979cad6..b4822af 100644 --- a/friends/urls.py +++ b/friends/urls.py @@ -7,8 +7,6 @@ views.friend_restaurant_list, name="friend-restaurant-list", ), - path("friends/", views.friend_list, name="friend-list"), - path("friend-recommend/", views.friend_recommend, name="friend-recommend"), # 추가 기능을 테스트하기 위한 url으로 실제로는 /friend 안에서 모두 진행됨 path("friend-request/", views.FriendRequestView.as_view(), name="friend-request"), path("friends/", views.friend_list, name="friend-list"), From 07eb5b638827259668d5a0544088945471c8c84e Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:25:15 +0900 Subject: [PATCH 11/22] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 134 ----------------------------------------- friends/views.py | 4 +- 2 files changed, 3 insertions(+), 135 deletions(-) diff --git a/friends/serializers.py b/friends/serializers.py index 10a5f81..13aee59 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -132,140 +132,6 @@ def get_rating_average(self, obj): return obj.rating_average() -class UserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = ["id", "name", "profile_img", "reliability"] - - -class FriendRequestSerializer(serializers.ModelSerializer): - id = serializers.IntegerField(source="from_user.id") - name = serializers.CharField(source="from_user.name") - profile_img = serializers.URLField(source="from_user.profile_img.url") - reliability = serializers.IntegerField(source="from_user.reliability") - common_restaurant_count = serializers.SerializerMethodField() - - class Meta: - model = FriendRequest - fields = [ - "id", - "name", - "profile_img", - "reliability", - "common_restaurant_count", - ] - - def get_common_restaurant_count(self, obj): - try: - user = obj.from_user - # friend_user = self.context.get('request').user - friend_user = User.objects.get(id=21) - - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = set( - UserRestaurantsList.objects.filter(user=friend_user).values_list( - "restaurant_id", flat=True - ) - ) - return len(user_restaurants.intersection(friend_restaurants)) - except User.DoesNotExist: - return 0 - - -class FriendRecommendSerializer(serializers.ModelSerializer): - common_restaurant_count = serializers.SerializerMethodField() - common_restaurants = serializers.SerializerMethodField() - - class Meta: - model = User - fields = [ - "id", - "name", - "profile_img", - "reliability", - "common_restaurant_count", - "common_restaurants", - ] - - def get_common_restaurant_count(self, obj): - user = self.context.get("user") - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = set( - UserRestaurantsList.objects.filter(user=obj).values_list( - "restaurant_id", flat=True - ) - ) - return len(user_restaurants.intersection(friend_restaurants)) - - def get_common_restaurants(self, obj): - user = self.context.get("user") - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = UserRestaurantsList.objects.filter( - user=obj, restaurant_id__in=user_restaurants - ).values("restaurant__name", "restaurant__image_url")[:2] - return friend_restaurants - - def to_representation(self, instance): - representation = super().to_representation(instance) - include_restaurants = self.context.get("include_restaurants", False) - if not include_restaurants: - representation.pop("common_restaurants") - return representation - - -class FriendSerializer(serializers.ModelSerializer): - id = serializers.IntegerField(source="friend.id") - name = serializers.CharField(source="friend.name") - profile_img = serializers.URLField(source="friend.profile_img.url") - reliability = serializers.IntegerField(source="friend.reliability") - - class Meta: - model = Friend - fields = [ - "id", - "name", - "profile_img", - "reliability", - ] - - -class RestaurantlistSerializer(serializers.ModelSerializer): - rating_average = serializers.SerializerMethodField() - - class Meta: - model = Restaurant - fields = [ - "id", - "name", - "food_type", - "rating_average", - "latitude", - "longitude", - "image_url", - ] - - def get_rating_average(self, obj): - return obj.rating_average() - - -class FriendRequestSerializer(serializers.ModelSerializer): - class Meta: - model = Friend - fields = "__all__" - - class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() diff --git a/friends/views.py b/friends/views.py index a662319..29a5e2c 100644 --- a/friends/views.py +++ b/friends/views.py @@ -14,13 +14,15 @@ FriendRequestSerializer, RestaurantlistSerializer, FriendRecommendSerializer, + RestaurantSerializer, ) + +# from .serializers import FriendSerializer, FriendRequestSerializer from accounts.models import User from .models import Friend, FriendRequest from django.views.decorators.csrf import csrf_exempt from django.db.models import Count, Q import random -from .serializers import RestaurantSerializer from django.shortcuts import get_object_or_404 From 6d81ee91b74a0f95f717802d86fc5c881631bd53 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:12:29 +0900 Subject: [PATCH 12/22] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD/=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/friends/serializers.py b/friends/serializers.py index 13aee59..4c9c395 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -132,6 +132,12 @@ def get_rating_average(self, obj): return obj.rating_average() +class FriendRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Friend + fields = "__all__" + + class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() From f26db9a167633a270e7287895f215331ce70428b Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:25:15 +0900 Subject: [PATCH 13/22] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 118 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/friends/serializers.py b/friends/serializers.py index 4c9c395..bb4caa9 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -133,9 +133,125 @@ def get_rating_average(self, obj): class FriendRequestSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="from_user.id") + name = serializers.CharField(source="from_user.name") + profile_img = serializers.URLField(source="from_user.profile_img.url") + reliability = serializers.IntegerField(source="from_user.reliability") + common_restaurant_count = serializers.SerializerMethodField() + + class Meta: + model = FriendRequest + fields = [ + "id", + "name", + "profile_img", + "reliability", + "common_restaurant_count", + ] + + def get_common_restaurant_count(self, obj): + try: + user = obj.from_user + # friend_user = self.context.get('request').user + friend_user = User.objects.get(id=21) + + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = set( + UserRestaurantsList.objects.filter(user=friend_user).values_list( + "restaurant_id", flat=True + ) + ) + return len(user_restaurants.intersection(friend_restaurants)) + except User.DoesNotExist: + return 0 + + +class FriendRecommendSerializer(serializers.ModelSerializer): + common_restaurant_count = serializers.SerializerMethodField() + common_restaurants = serializers.SerializerMethodField() + + class Meta: + model = User + fields = [ + "id", + "name", + "profile_img", + "reliability", + "common_restaurant_count", + "common_restaurants", + ] + + def get_common_restaurant_count(self, obj): + user = self.context.get("user") + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = set( + UserRestaurantsList.objects.filter(user=obj).values_list( + "restaurant_id", flat=True + ) + ) + return len(user_restaurants.intersection(friend_restaurants)) + + def get_common_restaurants(self, obj): + user = self.context.get("user") + user_restaurants = set( + UserRestaurantsList.objects.filter(user=user).values_list( + "restaurant_id", flat=True + ) + ) + friend_restaurants = UserRestaurantsList.objects.filter( + user=obj, restaurant_id__in=user_restaurants + ).values("restaurant__name", "restaurant__image_url")[:2] + return friend_restaurants + + def to_representation(self, instance): + representation = super().to_representation(instance) + include_restaurants = self.context.get("include_restaurants", False) + if not include_restaurants: + representation.pop("common_restaurants") + return representation + + +class FriendSerializer(serializers.ModelSerializer): + id = serializers.IntegerField(source="friend.id") + name = serializers.CharField(source="friend.name") + profile_img = serializers.URLField(source="friend.profile_img.url") + reliability = serializers.IntegerField(source="friend.reliability") + class Meta: model = Friend - fields = "__all__" + fields = [ + "id", + "name", + "profile_img", + "reliability", + ] + + +class RestaurantlistSerializer(serializers.ModelSerializer): + rating_average = serializers.SerializerMethodField() + + class Meta: + model = Restaurant + fields = [ + "id", + "name", + "food_type", + "rating_average", + "latitude", + "longitude", + "image_url", + ] + + def get_rating_average(self, obj): + return obj.rating_average() class RestaurantSerializer(serializers.ModelSerializer): From 835d642e888d8476dd1142940dfe908c15064a97 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:12:29 +0900 Subject: [PATCH 14/22] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD/=EC=88=98=EB=9D=BD/=EA=B1=B0=EC=A0=88=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 6 ++++++ friends/views.py | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/friends/serializers.py b/friends/serializers.py index bb4caa9..e0d6254 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -254,6 +254,12 @@ def get_rating_average(self, obj): return obj.rating_average() +class FriendRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Friend + fields = "__all__" + + class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() diff --git a/friends/views.py b/friends/views.py index 29a5e2c..e79fab4 100644 --- a/friends/views.py +++ b/friends/views.py @@ -2,6 +2,10 @@ from rest_framework.decorators import api_view from rest_framework.views import APIView +# from rest_framework.authentication import TokenAuthentication +# from rest_framework.permissions import IsAuthenticated +from rest_framework.views import APIView + # from rest_framework.authentication import TokenAuthentication # from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -14,7 +18,7 @@ FriendRequestSerializer, RestaurantlistSerializer, FriendRecommendSerializer, - RestaurantSerializer, + # RestaurantSerializer, ) # from .serializers import FriendSerializer, FriendRequestSerializer From 7df266efddef9bed3fdba069c4556530bbc51836 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 02:25:15 +0900 Subject: [PATCH 15/22] =?UTF-8?q?fix:=20=EC=B6=A9=EB=8F=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/serializers.py | 128 ----------------------------------------- friends/views.py | 18 +++--- 2 files changed, 7 insertions(+), 139 deletions(-) diff --git a/friends/serializers.py b/friends/serializers.py index e0d6254..13aee59 100644 --- a/friends/serializers.py +++ b/friends/serializers.py @@ -132,134 +132,6 @@ def get_rating_average(self, obj): return obj.rating_average() -class FriendRequestSerializer(serializers.ModelSerializer): - id = serializers.IntegerField(source="from_user.id") - name = serializers.CharField(source="from_user.name") - profile_img = serializers.URLField(source="from_user.profile_img.url") - reliability = serializers.IntegerField(source="from_user.reliability") - common_restaurant_count = serializers.SerializerMethodField() - - class Meta: - model = FriendRequest - fields = [ - "id", - "name", - "profile_img", - "reliability", - "common_restaurant_count", - ] - - def get_common_restaurant_count(self, obj): - try: - user = obj.from_user - # friend_user = self.context.get('request').user - friend_user = User.objects.get(id=21) - - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = set( - UserRestaurantsList.objects.filter(user=friend_user).values_list( - "restaurant_id", flat=True - ) - ) - return len(user_restaurants.intersection(friend_restaurants)) - except User.DoesNotExist: - return 0 - - -class FriendRecommendSerializer(serializers.ModelSerializer): - common_restaurant_count = serializers.SerializerMethodField() - common_restaurants = serializers.SerializerMethodField() - - class Meta: - model = User - fields = [ - "id", - "name", - "profile_img", - "reliability", - "common_restaurant_count", - "common_restaurants", - ] - - def get_common_restaurant_count(self, obj): - user = self.context.get("user") - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = set( - UserRestaurantsList.objects.filter(user=obj).values_list( - "restaurant_id", flat=True - ) - ) - return len(user_restaurants.intersection(friend_restaurants)) - - def get_common_restaurants(self, obj): - user = self.context.get("user") - user_restaurants = set( - UserRestaurantsList.objects.filter(user=user).values_list( - "restaurant_id", flat=True - ) - ) - friend_restaurants = UserRestaurantsList.objects.filter( - user=obj, restaurant_id__in=user_restaurants - ).values("restaurant__name", "restaurant__image_url")[:2] - return friend_restaurants - - def to_representation(self, instance): - representation = super().to_representation(instance) - include_restaurants = self.context.get("include_restaurants", False) - if not include_restaurants: - representation.pop("common_restaurants") - return representation - - -class FriendSerializer(serializers.ModelSerializer): - id = serializers.IntegerField(source="friend.id") - name = serializers.CharField(source="friend.name") - profile_img = serializers.URLField(source="friend.profile_img.url") - reliability = serializers.IntegerField(source="friend.reliability") - - class Meta: - model = Friend - fields = [ - "id", - "name", - "profile_img", - "reliability", - ] - - -class RestaurantlistSerializer(serializers.ModelSerializer): - rating_average = serializers.SerializerMethodField() - - class Meta: - model = Restaurant - fields = [ - "id", - "name", - "food_type", - "rating_average", - "latitude", - "longitude", - "image_url", - ] - - def get_rating_average(self, obj): - return obj.rating_average() - - -class FriendRequestSerializer(serializers.ModelSerializer): - class Meta: - model = Friend - fields = "__all__" - - class RestaurantSerializer(serializers.ModelSerializer): # reviews = serializers.SerializerMethodField() diff --git a/friends/views.py b/friends/views.py index e79fab4..ff4c688 100644 --- a/friends/views.py +++ b/friends/views.py @@ -2,10 +2,6 @@ from rest_framework.decorators import api_view from rest_framework.views import APIView -# from rest_framework.authentication import TokenAuthentication -# from rest_framework.permissions import IsAuthenticated -from rest_framework.views import APIView - # from rest_framework.authentication import TokenAuthentication # from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -18,13 +14,13 @@ FriendRequestSerializer, RestaurantlistSerializer, FriendRecommendSerializer, - # RestaurantSerializer, ) # from .serializers import FriendSerializer, FriendRequestSerializer from accounts.models import User from .models import Friend, FriendRequest -from django.views.decorators.csrf import csrf_exempt + +# from django.views.decorators.csrf import csrf_exempt from django.db.models import Count, Q import random @@ -52,9 +48,9 @@ def friend_restaurant_list(request, id): ) -@csrf_exempt @api_view(["GET"]) -# @login_required +# @authentication_classes([TokenAuthentication]) +# @permission_classes([IsAuthenticated]) def friend_list(request): try: # user = request.user @@ -102,9 +98,9 @@ def friend_list(request): return Response({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND) -@csrf_exempt @api_view(["GET"]) -# @login_required +# @authentication_classes([TokenAuthentication]) +# @permission_classes([IsAuthenticated]) def friend_recommend(request): try: # user = request.user @@ -220,4 +216,4 @@ def decline_request(self, request, friend_id): friend_request.state = "declined" friend_request.save() - return Response({"message": "친구 신청을 거절했습니다."}, status=status.HTTP_200_OK) + return Response({"message": "친구 신청을 거절했습니다."}, status=status.HTTP_200_OK) \ No newline at end of file From 32fb5828af8ec3284b2ab290e4e5ff05b6bab927 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Mon, 5 Aug 2024 03:02:32 +0900 Subject: [PATCH 16/22] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- friends/models.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/friends/models.py b/friends/models.py index 41e315d..cd13ef2 100644 --- a/friends/models.py +++ b/friends/models.py @@ -1,8 +1,6 @@ from django.db import models from accounts.models import User -# Create your models here. - class Friend(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="friends") From 599b7266a90d4c242f71ec1072fe2a0261369339 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Tue, 6 Aug 2024 01:59:33 +0900 Subject: [PATCH 17/22] =?UTF-8?q?fix:=20settings.py=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mustgou/settings.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mustgou/settings.py b/mustgou/settings.py index 05a74bc..f65b19b 100644 --- a/mustgou/settings.py +++ b/mustgou/settings.py @@ -115,11 +115,11 @@ }, ] -REST_FRAMEWORK = { - "DEFAULT_AUTHENTICATION_CLASSES": [ - "rest_framework.authentication.TokenAuthentication", - ] -} +# REST_FRAMEWORK = { +# "DEFAULT_AUTHENTICATION_CLASSES": [ +# "rest_framework.authentication.TokenAuthentication", +# ] +# } CORS_ALLOWED_ORIGINS = config("CORS_ALLOWED_ORIGINS", default="").split(",") @@ -151,7 +151,7 @@ LANGUAGE_CODE = "en-us" -TIME_ZONE = "UTC" +TIME_ZONE = "Asia/Seoul" USE_I18N = True From 7a6f2e0ff8f4b9567b5e8641273a7e25422ea532 Mon Sep 17 00:00:00 2001 From: dkfla Date: Mon, 5 Aug 2024 21:02:05 +0900 Subject: [PATCH 18/22] =?UTF-8?q?chore:=20=EC=97=90=EB=9F=AC=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restaurants/views.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/restaurants/views.py b/restaurants/views.py index 61dd7f1..c67b242 100644 --- a/restaurants/views.py +++ b/restaurants/views.py @@ -39,7 +39,10 @@ def search(request): elif request.method == "POST": query = request.data.get("query", "") if not query: - return Response({"error": "No search query provided"}, status=400) + return Response( + {"error": "No search query provided"}, + status=status.HTTP_400_BAD_REQUEST, + ) SearchHistory.objects.create(user=user, query=query) # 추후 삭제 # SearchHistory.objects.create(user=request.user, query=query) @@ -53,17 +56,24 @@ def search(request): elif request.method == "DELETE": history_id = request.data.get("id", "") if not history_id: - return Response({"error": "No history ID provided"}, status=400) + return Response( + {"error": "No history ID provided"}, status=status.HTTP_400_BAD_REQUEST + ) try: history_to_delete = SearchHistory.objects.get(id=history_id, user=user) history_to_delete.delete() return Response({"message": "Search history deleted successfully"}) except SearchHistory.DoesNotExist: - return Response({"error": "No matching search history found"}, status=404) + return Response( + {"error": "No matching search history found"}, + status=status.HTTP_404_NOT_FOUND, + ) else: - return Response({"error": "Unsupported method"}, status=405) + return Response( + {"error": "Unsupported method"}, status=status.HTTP_405_METHOD_NOT_ALLOWED + ) @csrf_exempt From b23c3098cdc6138794c8fecc98b3c81724d792ce Mon Sep 17 00:00:00 2001 From: dkfla Date: Mon, 5 Aug 2024 21:13:56 +0900 Subject: [PATCH 19/22] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=EC=96=B4=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restaurants/views.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/restaurants/views.py b/restaurants/views.py index c67b242..ce9283c 100644 --- a/restaurants/views.py +++ b/restaurants/views.py @@ -15,6 +15,7 @@ from django.views.decorators.csrf import csrf_exempt import logging from accounts.models import User # 임시 유저 지정을 위한 임포트, 추후 삭제 +from django.db.models import Q @csrf_exempt @@ -47,7 +48,12 @@ def search(request): SearchHistory.objects.create(user=user, query=query) # 추후 삭제 # SearchHistory.objects.create(user=request.user, query=query) - restaurants = Restaurant.objects.filter(name__icontains=query) + query_terms = query.split() + q_objects = Q() + for term in query_terms: + q_objects |= Q(name__icontains=term) | Q(food_type__icontains=term) + + restaurants = Restaurant.objects.filter(q_objects).distinct() serializer = RestaurantListSerializer(restaurants, many=True) data = serializer.data logging.debug("Serialized data: %s", data) From c1dd65845d59a5bbd0c89fbcf990ac73821a86b1 Mon Sep 17 00:00:00 2001 From: dkfla Date: Mon, 5 Aug 2024 21:21:15 +0900 Subject: [PATCH 20/22] =?UTF-8?q?chore:=20search=20=EC=8A=AC=EB=9E=98?= =?UTF-8?q?=EC=8B=9C=20=EC=97=86=EB=8A=94=20url=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mustgou/settings.py | 2 ++ restaurants/urls.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mustgou/settings.py b/mustgou/settings.py index f65b19b..8a599fd 100644 --- a/mustgou/settings.py +++ b/mustgou/settings.py @@ -177,3 +177,5 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" LOGIN_URL = "/auth/login/" + +APPEND_SLASH = True diff --git a/restaurants/urls.py b/restaurants/urls.py index 4d81551..5e7d72f 100644 --- a/restaurants/urls.py +++ b/restaurants/urls.py @@ -1,4 +1,4 @@ -from django.urls import path, include +from django.urls import path, include, re_path from . import views @@ -6,6 +6,7 @@ # path("restaurants/", views.restaurant_list, name="restaurant-list"), path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), path("search/", views.search, name="search"), + re_path(r"^search$", views.search), path( "restaurants//", views.add_remove_restaurant, From 7e9bc655c96fef1fd3680ddc83465846e99b60b8 Mon Sep 17 00:00:00 2001 From: dkfla Date: Mon, 5 Aug 2024 21:56:59 +0900 Subject: [PATCH 21/22] =?UTF-8?q?chore:=20=EC=9D=B8=EC=A6=9D=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restaurants/views.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/restaurants/views.py b/restaurants/views.py index ce9283c..c2b6b12 100644 --- a/restaurants/views.py +++ b/restaurants/views.py @@ -11,6 +11,8 @@ RestaurantDetailSerializer, ) +# from rest_framework.authentication import TokenAuthentication +# from rest_framework.permissions import IsAuthenticated # from django.contrib.auth.decorators import login_required from django.views.decorators.csrf import csrf_exempt import logging @@ -26,9 +28,9 @@ def restaurant_list(request): return Response(serializer.data) -@csrf_exempt @api_view(["GET", "POST", "DELETE"]) -# @login_required +# @authentication_classes([TokenAuthentication]) +# @permission_classes([IsAuthenticated]) def search(request): user = User.objects.get(id=21) # 임시 유저 지정, 추후 삭제 if request.method == "GET": @@ -138,9 +140,9 @@ def add_remove_restaurant(request, pk): ) -@csrf_exempt @api_view(["GET"]) -# @login_required +# @authentication_classes([TokenAuthentication]) +# @permission_classes([IsAuthenticated]) def restaurant_detail(request, pk): try: restaurant = Restaurant.objects.prefetch_related("reviews").get(pk=pk) From 9a7f136b3a646a4e952acbdfb56f35bdf90eff02 Mon Sep 17 00:00:00 2001 From: ybkang1108 Date: Tue, 6 Aug 2024 02:19:22 +0900 Subject: [PATCH 22/22] =?UTF-8?q?fix:=20=EC=84=B8=ED=8C=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=84=9C=EB=B2=84=20=EC=8B=9C=EA=B0=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20=EC=84=B8=EC=85=98=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20DRF=EC=97=90=EC=84=9C=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=9C=A0=EC=A7=80=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EC=9D=B8=EC=A6=9D=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mustgou/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mustgou/settings.py b/mustgou/settings.py index 8a599fd..ba164c0 100644 --- a/mustgou/settings.py +++ b/mustgou/settings.py @@ -115,6 +115,7 @@ }, ] +# DRF 로그인 유지를 위해 주석처리 # REST_FRAMEWORK = { # "DEFAULT_AUTHENTICATION_CLASSES": [ # "rest_framework.authentication.TokenAuthentication",