profiles: friends reworked

This commit is contained in:
AdrienLSH 2024-04-09 13:12:15 +02:00
parent 9f5ca1430d
commit 90d179eb72
6 changed files with 80 additions and 36 deletions

View File

@ -1,7 +1,8 @@
from django.contrib.auth.models import User
from django.db import models from django.db import models
from . import ProfileModel
class FriendModel(models.Model): class FriendModel(models.Model):
friend1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friend1') friend1 = models.ForeignKey(ProfileModel.ProfileModel, on_delete=models.CASCADE, related_name='friend1')
friend2 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friend2') friend2 = models.ForeignKey(ProfileModel.ProfileModel, on_delete=models.CASCADE, related_name='friend2')

View File

@ -1,21 +1,22 @@
from __future__ import annotations
from os.path import splitext from os.path import splitext
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db.models import Q, Model, CASCADE, ForeignKey, ImageField
from django.db.models.signals import post_save, pre_delete from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from games.consumers import game_manager from games.consumers import game_manager
from ..models.FriendModel import FriendModel from . import FriendModel
def upload_to(instance, filename: str): def upload_to(instance, filename: str):
return f"./profiles/static/avatars/{instance.pk}{splitext(filename)[1]}" return f"./profiles/static/avatars/{instance.pk}{splitext(filename)[1]}"
class ProfileModel(models.Model): class ProfileModel(Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = ForeignKey(User, on_delete=CASCADE)
avatar = models.ImageField(upload_to=upload_to, default="./profiles/static/avatars/default.avif") avatar = ImageField(upload_to=upload_to, default="./profiles/static/avatars/default.avif")
def get_game(self) -> int: def get_game(self) -> int:
for game in game_manager._game_list: for game in game_manager._game_list:
@ -24,20 +25,23 @@ class ProfileModel(models.Model):
return game.game_id return game.game_id
return None return None
def getFriends(self): def get_friends(self) -> list[ProfileModel]:
friends = [] friends: list[ProfileModel] = []
for friendship in FriendModel.objects.filter(models.Q(friend1=self.user) | models.Q(friend2=self.user)): for friendship in FriendModel.FriendModel.objects.filter(Q(friend1=self) | Q(friend2=self)):
friends.append(friendship.friend1 if friendship.friend1 != self.user else friendship.friend2) friends.append(friendship.friend1 if friendship.friend1 != self else friendship.friend2)
return friends return friends
def isFriend(self, user): def is_friend(self, friend):
return user in self.getFriends() return friend in self.get_friends()
def deleteFriend(self, user): def delete_friend(self, friend):
for friendship in FriendModel.objects.filter(models.Q(friend1=self.user) | models.Q(friend2=self.user)): print(friend)
friendship.delete() FriendModel.FriendModel.objects.get(
(Q(friend1=self) & Q(friend2=friend)) |
(Q(friend2=self) & Q(friend1=friend))
).delete()
@receiver(pre_delete, sender=ProfileModel) @receiver(pre_delete, sender=ProfileModel)

View File

@ -6,18 +6,6 @@ from rest_framework import status
from profiles.serializers.ProfileSerializer import ProfileSerializer from profiles.serializers.ProfileSerializer import ProfileSerializer
from profiles.models.ProfileModel import ProfileModel from profiles.models.ProfileModel import ProfileModel
class ProfileTest(TestCase):
def setUp(self):
self.user: User = User.objects.create_user('bozo', password='password')
self.user.save()
self.expected_response = {'avatar': '/static/avatars/default.avif', 'user_id': 1, 'username': 'bozo'}
self.url = "/api/profiles/user/"
def test_profile_create_on_user_created(self):
response: HttpResponse = self.client.get(self.url + self.user.username)
self.assertDictEqual(self.expected_response, response.json())
class BlockTest(TestCase): class BlockTest(TestCase):
def setUp(self): def setUp(self):

View File

@ -0,0 +1,16 @@
from django.test import TestCase
from django.http import HttpResponse
from django.contrib.auth.models import User
class ProfileTest(TestCase):
def setUp(self):
self.user: User = User.objects.create_user('bozo', password='password')
self.user.save()
self.expected_response = {'avatar': '/static/avatars/default.avif', 'user_id': 1, 'username': 'bozo'}
self.url = "/api/profiles/user/"
def test_profile_create_on_user_created(self):
response: HttpResponse = self.client.get(self.url + self.user.username)
self.assertDictEqual(self.expected_response, response.json())

View File

@ -3,6 +3,7 @@ from django.urls import path
from .viewsets.ProfileViewSet import ProfileViewSet from .viewsets.ProfileViewSet import ProfileViewSet
from .viewsets.MyProfileViewSet import MyProfileViewSet from .viewsets.MyProfileViewSet import MyProfileViewSet
from .views.blocks import GetBlocksView, EditBlocksView from .views.blocks import GetBlocksView, EditBlocksView
from .views.friends import GetFriendsView, EditFriendView
urlpatterns = [ urlpatterns = [
path("settings", MyProfileViewSet.as_view({'patch': 'partial_update', 'delete': 'delete_avatar'}), name="my_profile_page"), path("settings", MyProfileViewSet.as_view({'patch': 'partial_update', 'delete': 'delete_avatar'}), name="my_profile_page"),
@ -10,7 +11,8 @@ urlpatterns = [
path("", ProfileViewSet.as_view({'get': 'list'}), name="profiles_list"), path("", ProfileViewSet.as_view({'get': 'list'}), name="profiles_list"),
path("block", GetBlocksView.as_view(), name="block_page"), path("block", GetBlocksView.as_view(), name="block_page"),
path("block/<int:pk>", EditBlocksView.as_view(), name="block_page"), path("block/<int:pk>", EditBlocksView.as_view(), name="block_page"),
# path("friend", views.FriendsView.as_view(), name="friend_page"), path("friends", GetFriendsView.as_view(), name="friends_list_page"),
path("friends/<int:pk>", EditFriendView.as_view(), name="friends_edit_page"),
path("user/<str:username>", ProfileViewSet.as_view({'get': 'retrieve'}), name="profile_page"), path("user/<str:username>", ProfileViewSet.as_view({'get': 'retrieve'}), name="profile_page"),
path("id/<int:pk>", ProfileViewSet.as_view({'get': 'retrieve_id'}), name="profile_page"), path("id/<int:pk>", ProfileViewSet.as_view({'get': 'retrieve_id'}), name="profile_page"),
] ]

View File

@ -4,16 +4,49 @@ from rest_framework import permissions, status
from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import SessionAuthentication
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.db.models import Q
from django.shortcuts import get_object_or_404
from ..models.FriendModel import FriendModel from ..models.FriendModel import FriendModel
from ..models.ProfileModel import ProfileModel
from ..serializers.ProfileSerializer import ProfileSerializer
class FriendsView(APIView): class GetFriendsView(APIView):
permission_classes = (permissions.IsAuthenticated,) permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,) authentication_classes = (SessionAuthentication,)
def get(self, request): def get(self, request):
friends = FriendModel.getFriends(request.user.pk) query = ProfileModel.objects.filter(user=request.user)
if (friends): if not query.exists():
return Response({"friends": friends, "user_id": request.user.pk}, status=status.HTTP_200_OK) return Response(status=status.HTTP_400_BAD_REQUEST)
return Response({}, status=status.HTTP_204_NO_CONTENT) friends = query[0].get_friends()
return Response(ProfileSerializer(friends, many=True).data)
class EditFriendView(APIView):
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
def get_object(self):
return ProfileModel.objects.get(pk=self.request.user.pk)
def post(self, request, pk=None):
user_profile = self.get_object()
friend_profile = get_object_or_404(ProfileModel, pk=pk)
if user_profile.is_friend(friend_profile):
return Response(_('You are already friend with this user.'), status.HTTP_400_BAD_REQUEST)
FriendModel(friend1=user_profile, friend2=friend_profile).save()
return Response(_('Friendship succssfully created.'), status.HTTP_201_CREATED)
def delete(self, request, pk=None):
user_profile = self.get_object()
friend_profile = get_object_or_404(ProfileModel, pk=pk)
if not user_profile.is_friend(friend_profile):
return Response(_('You are not friend with this user.'), status.HTTP_400_BAD_REQUEST)
user_profile.delete_friend(friend_profile)
return Response(_('Friendship succssfully deleted.'))