Skip to content

Commit

Permalink
feat: 친구 추천 기능
Browse files Browse the repository at this point in the history
  • Loading branch information
dkfla committed Aug 4, 2024
1 parent a648a09 commit ebd846c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
42 changes: 42 additions & 0 deletions friends/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,48 @@ def get_common_restaurant_count(self, obj):
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


class FriendSerializer(serializers.ModelSerializer):
friend = UserSerializer(read_only=True)

Expand Down
1 change: 1 addition & 0 deletions friends/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
name="friend-restaurant-list",
),
path("friends/", views.friend_list, name="friend-list"),
path("friend-recommend/", views.friend_recommend, name="friend-recommend"),
]
63 changes: 63 additions & 0 deletions friends/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
FriendSerializer,
FriendRequestSerializer,
RestaurantlistSerializer,
FriendRecommendSerializer,
)
from accounts.models import User
from .models import Friend
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Count, Q
import random


@api_view(["GET"])
Expand Down Expand Up @@ -51,12 +54,72 @@ def friend_list(request):
friends = Friend.objects.filter(user=user, state="approve")
friends_serialized = FriendSerializer(friends, many=True).data

user_restaurants = set(
UserRestaurantsList.objects.filter(user=user).values_list(
"restaurant_id", flat=True
)
)
potential_friends = (
User.objects.exclude(id=user.id)
.annotate(
common_restaurant_count=Count(
"userrestaurantslist__restaurant_id",
filter=Q(userrestaurantslist__restaurant_id__in=user_restaurants),
)
)
.order_by("-common_restaurant_count")[:7]
)

friend_recommend_serialized = FriendRecommendSerializer(
potential_friends, many=True, context={"request": request, "user": user}
).data

data = {
"friend_request": friend_request_serialized,
"friends": friends_serialized,
"friend_recommend": friend_recommend_serialized,
}

return Response(data)

except User.DoesNotExist:
return Response({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)


@csrf_exempt
@api_view(["GET"])
# @login_required
def friend_recommend(request):
try:
user = User.objects.get(id=21)

user_restaurants = set(
UserRestaurantsList.objects.filter(user=user).values_list(
"restaurant_id", flat=True
)
)
potential_friends = (
User.objects.exclude(id=user.id)
.annotate(
common_restaurant_count=Count(
"userrestaurantslist__restaurant_id",
filter=Q(userrestaurantslist__restaurant_id__in=user_restaurants),
)
)
.order_by("-common_restaurant_count")[:7]
)

if potential_friends:
random_friend = random.choice(potential_friends)
friend_recommend_serialized = FriendRecommendSerializer(
random_friend, context={"request": request, "user": user}
).data
return Response({"friend_recommend": friend_recommend_serialized})

return Response(
{"message": "No recommended friends found"},
status=status.HTTP_404_NOT_FOUND,
)

except User.DoesNotExist:
return Response({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)
23 changes: 23 additions & 0 deletions reviews/migrations/0003_alter_review_restaurant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.14 on 2024-08-04 11:14

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("restaurants", "0005_restaurant_food_type"),
("reviews", "0002_alter_recommend_user_alter_review_user"),
]

operations = [
migrations.AlterField(
model_name="review",
name="restaurant",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="reviews",
to="restaurants.restaurant",
),
),
]

0 comments on commit ebd846c

Please sign in to comment.