Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend] Comments/answers API #309

Merged
merged 11 commits into from
Jan 2, 2022
1 change: 0 additions & 1 deletion backend/badges/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from rest_framework.response import Response



class BadgeViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
authentication_classes = [JWTAuthentication]
Expand Down
19 changes: 18 additions & 1 deletion backend/equipmentposts/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from django.db import models
from eventposts.models import Post
from authentication.models import User
from datetime import datetime

# Create your models here.


Expand All @@ -8,4 +11,18 @@ class EquipmentPost(Post):
equipment_type = models.TextField()

class Meta:
app_label = 'equipmentposts'
app_label = 'equipmentposts'


class Comment(models.Model):
parent_equipment = models.ForeignKey(EquipmentPost, on_delete=models.CASCADE)
content = models.TextField()
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="equipment_comment")
supiket marked this conversation as resolved.
Show resolved Hide resolved
created_date = models.DateTimeField(default=datetime.now())


class Answer(models.Model):
parent_comment = models.ForeignKey(Comment, on_delete=models.CASCADE)
content = models.TextField()
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="equipment_answer")
created_date = models.DateTimeField(default=datetime.now())
19 changes: 17 additions & 2 deletions backend/equipmentposts/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
from rest_framework import serializers
from equipmentposts.models import EquipmentPost
from equipmentposts.models import EquipmentPost, Comment, Answer


class EquipmentSerializer(serializers.ModelSerializer):
class Meta:
model = EquipmentPost
fields = "__all__"
fields = "__all__"


class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ["parent_equipment", "owner", "created_date"]


class AnswerSerializer(serializers.ModelSerializer):
class Meta:
model = Answer
fields = "__all__"
read_only_fields = ["parent_comment", "owner", "created_date"]
12 changes: 6 additions & 6 deletions backend/equipmentposts/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,37 +56,37 @@ def setUp(self):


def test_filter_by_query(self):
response = self.client.get(reverse('equipmentpost-list'), {'query': 'basketball'}, HTTP_AUTHORIZATION=f'JWT {self.token}')
response = self.client.get(reverse('equipments-list'), {'query': 'basketball'}, HTTP_AUTHORIZATION=f'JWT {self.token}')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'], self.basketball_ads)

def test_filter_by_creation_date(self):
response = self.client.get(reverse('equipmentpost-list'), {'min_creation_date': (datetime.today() - timedelta(3)),
response = self.client.get(reverse('equipments-list'), {'min_creation_date': (datetime.today() - timedelta(3)),
'max_creation_date': (datetime.today() + timedelta(1))},
HTTP_AUTHORIZATION=f'JWT {self.token}')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'], self.creation_date_today)

def test_filter_by_location(self):
response = self.client.get(reverse('equipmentpost-list'), {'location': 'le'},
response = self.client.get(reverse('equipments-list'), {'location': 'le'},
HTTP_AUTHORIZATION=f'JWT {self.token}')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'], self.in_turkey_ads)

def test_filter_by_sport(self):
response = self.client.get(reverse('equipmentpost-list'), {'sport': 'Basketball'},
response = self.client.get(reverse('equipments-list'), {'sport': 'Basketball'},
HTTP_AUTHORIZATION=f'JWT {self.token}')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'], self.basketball_ads)

def test_filter_by_owner(self):
response = self.client.get(reverse('equipmentpost-list'), {'owner_id': self.user.id},
response = self.client.get(reverse('equipments-list'), {'owner_id': self.user.id},
HTTP_AUTHORIZATION=f'JWT {self.token}')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'], self.ads_created_by_user)

def test_filter_by_coordinates(self):
response = self.client.get(reverse('equipmentpost-list'), {'min_latitude': 36.23763062438484,
response = self.client.get(reverse('equipments-list'), {'min_latitude': 36.23763062438484,
'max_latitude': 42.01901802424485,
'min_longitude': 26.732105369671633,
'max_longitude': 44.3513027746188},
Expand Down
21 changes: 15 additions & 6 deletions backend/equipmentposts/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from . import views
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register(r'equipments', views.EquipmentViewSet)
urlpatterns = router.urls
from rest_framework_extensions.routers import ExtendedSimpleRouter
from .views import EquipmentViewSet, CommentViewSet, AnswerViewSet
router = ExtendedSimpleRouter()
(
router.register(r'equipments', EquipmentViewSet, basename='equipments')
.register(r'comments',
CommentViewSet,
basename='posts-comment',
parents_query_lookups=['parent_equipment_id'])
.register(r'answers',
AnswerViewSet,
basename='posts-comments-answer',
parents_query_lookups=['parent_comment_id__parent_equipment_id', 'parent_comment_id'])
)
urlpatterns = router.urls
227 changes: 224 additions & 3 deletions backend/equipmentposts/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from equipmentposts.models import EquipmentPost
from rest_framework_extensions.mixins import NestedViewSetMixin

from equipmentposts.models import EquipmentPost, Comment, Answer
from authentication.models import User
from equipmentposts.serializers import EquipmentSerializer
from equipmentposts.serializers import EquipmentSerializer, CommentSerializer, AnswerSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.http import JsonResponse
from rest_framework import status
Expand All @@ -16,7 +18,8 @@ class EquipmentPostsPagination(PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = 1000

class EquipmentViewSet(viewsets.ModelViewSet):

class EquipmentViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
authentication_classes = [JWTAuthentication]
pagination_class = EquipmentPostsPagination
Expand Down Expand Up @@ -139,3 +142,221 @@ def create(self, request, *args, **kwargs):
return Response(self.wrap(request, serializer.data), status=status.HTTP_201_CREATED, headers=headers)
else:
return JsonResponse(status=401, data={'detail': 'Unauthorized.'})


class CommentViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
authentication_classes = [JWTAuthentication]
queryset = Comment.objects.all()
serializer_class = CommentSerializer
lookup_field = 'id'

def wrap(self, data):
response = \
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": data["owner_username"] + " created a comment",
"type": "Create",
"actor": {
"type": "Person",
"name": data["owner_username"]
},
"object":
{
"type": "Comment",
"equipmentId": data["equipment_id"],
"id": data["id"],
"ownerId": data["owner_id"],
"content": data["content"],
"creationDate": data["creation_date"]
}
}

return response

def wrap_all(self, objects):
response = \
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Object history",
"type": "Collection",
"totalItems": len(objects),
"items": objects
}

return response

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
data =\
{
"owner_username": self.request.user.username,
"equipment_id": self.kwargs["parent_lookup_parent_equipment_id"],
"owner_id": self.request.user.id,
"content": serializer.data["content"],
"creation_date": serializer.data["created_date"],
"id": serializer.data["id"]
}
return Response(self.wrap(data), status=status.HTTP_201_CREATED, headers=headers)

def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
owner_id = serializer.data["owner"]
owner_username = User.objects.get(id=owner_id).username
data =\
{
"owner_username": owner_username,
"equipment_id": serializer.data["parent_equipment"],
"owner_id": owner_id,
"content": serializer.data["content"],
"creation_date": serializer.data["created_date"],
"id": serializer.data["id"]
}
return Response(self.wrap(data))

def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)

objects = []

for item in serializer.data:
owner_id = item["owner"]
owner_username = User.objects.get(id=owner_id).username
data = \
{
"owner_username": owner_username,
"equipment_id": item["parent_equipment"],
"owner_id": owner_id,
"content": item["content"],
"creation_date": item["created_date"],
"id": item["id"]
}
objects.append(self.wrap(data))

return Response(self.wrap_all(objects))

def perform_create(self, serializer):
serializer.save(parent_equipment_id=self.kwargs["parent_lookup_parent_equipment_id"], owner=self.request.user)


class AnswerViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
authentication_classes = [JWTAuthentication]
queryset = Answer.objects.all()
serializer_class = AnswerSerializer
lookup_field = 'id'

def wrap(self, data):
response = \
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": data["owner_username"] + " created an answer",
"type": "Create",
"actor": {
"type": "Person",
"name": data["owner_username"]
},
"object":
{
"type": "Answer",
"commentId": data["comment_id"],
"equipmentId": data["equipment_id"],
"id": data["id"],
"ownerId": data["owner_id"],
"content": data["content"],
"creationDate": data["creation_date"]
}
}

return response

def wrap_all(self, objects):
response = \
{
"@context": "https://www.w3.org/ns/activitystreams",
"summary": "Object history",
"type": "Collection",
"totalItems": len(objects),
"items": objects
}

return response

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
data =\
{
"owner_username": self.request.user.username,
"equipment_id": self.kwargs["parent_lookup_parent_comment_id__parent_equipment_id"],
"comment_id": self.kwargs["parent_lookup_parent_comment_id"],
"owner_id": self.request.user.id,
"content": serializer.data["content"],
"creation_date": serializer.data["created_date"],
"id": serializer.data["id"]
}
return Response(self.wrap(data), status=status.HTTP_201_CREATED, headers=headers)

def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
owner_id = serializer.data["owner"]
owner_username = User.objects.get(id=owner_id).username
equipment_id = Comment.objects.get(id=serializer.data["parent_comment"]).id
data =\
{
"owner_username": owner_username,
"comment_id": serializer.data["parent_comment"],
"equipment_id": equipment_id,
"owner_id": owner_id,
"content": serializer.data["content"],
"creation_date": serializer.data["created_date"],
"id": serializer.data["id"]
}
return Response(self.wrap(data))

def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)

objects = []

for item in serializer.data:
owner_id = item["owner"]
owner_username = User.objects.get(id=owner_id).username
equipment_id = Comment.objects.get(id=item["parent_comment"]).id
data = \
{
"owner_username": owner_username,
"comment_id": item["parent_comment"],
"equipment_id": equipment_id,
"owner_id": owner_id,
"content": item["content"],
"creation_date": item["created_date"],
"id": item["id"]
}
objects.append(self.wrap(data))

return Response(self.wrap_all(objects))

def perform_create(self, serializer):
serializer.save(parent_comment_id=self.kwargs["parent_lookup_parent_comment_id"], owner=self.request.user)
16 changes: 15 additions & 1 deletion backend/eventposts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,18 @@ class EventPost(Post):
max_skill_level = models.IntegerField(default=0)

class Meta:
app_label = 'eventposts'
app_label = 'eventposts'


class Comment(models.Model):
parent_post = models.ForeignKey(EventPost, on_delete=models.CASCADE)
content = models.TextField()
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="event_comment")
supiket marked this conversation as resolved.
Show resolved Hide resolved
created_date = models.DateTimeField(default=datetime.now())


class Answer(models.Model):
parent_comment = models.ForeignKey(Comment, on_delete=models.CASCADE)
content = models.TextField()
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="event_answer")
created_date = models.DateTimeField(default=datetime.now())
Loading