Skip to content

Commit f7ad267

Browse files
authored
Merge pull request #232 from PROCOLLAB-github/dev
draft field in user projects list
2 parents ad60da9 + 080833a commit f7ad267

7 files changed

Lines changed: 103 additions & 13 deletions

File tree

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ volumes:
6969
prom-data:
7070
prom-configs:
7171
log:
72-
redis_data:
72+
redis-data:

news/mixins.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,54 @@
1+
from django.contrib.auth import get_user_model
2+
13
from news.models import News
24
from partner_programs.models import PartnerProgram
35
from projects.models import Project
46

7+
User = get_user_model()
8+
59

610
class NewsQuerysetMixin:
711
"""
812
Mixin for getting queryset for news
913
"""
1014

1115
def get_queryset_for_project(self):
16+
"""Returns queryset of news for project"""
17+
project_pk = self.kwargs.get("project_pk")
1218
try:
13-
project = Project.objects.get(pk=self.kwargs.get("project_pk"))
19+
project = Project.objects.get(pk=project_pk)
1420
except Project.DoesNotExist:
21+
# TODO: raise http 404 here
1522
return News.objects.none()
1623
return News.objects.get_news(obj=project)
1724

1825
def get_queryset_for_program(self):
26+
"""Returns queryset of news for partner program"""
27+
partnerprogram_pk = self.kwargs.get("partnerprogram_pk")
1928
try:
20-
program = PartnerProgram.objects.get(pk=self.kwargs.get("partnerprogram_pk"))
29+
program = PartnerProgram.objects.get(pk=partnerprogram_pk)
2130
except PartnerProgram.DoesNotExist:
31+
# TODO: raise http 404 here
2232
return News.objects.none()
2333
return News.objects.get_news(obj=program)
2434

35+
def get_queryset_for_user(self):
36+
"""Returns queryset of news for user"""
37+
user_pk = self.kwargs.get("user_pk")
38+
try:
39+
user = User.objects.get(pk=user_pk)
40+
except User.DoesNotExist:
41+
# TODO: raise http 404 here
42+
return News.objects.none()
43+
return News.objects.get_news(obj=user)
44+
2545
def get_queryset(self):
46+
"""Chooses what queryset to return - for project, program or user"""
2647
if self.kwargs.get("project_pk") is not None:
27-
# it's a project
2848
return self.get_queryset_for_project()
2949
elif self.kwargs.get("partnerprogram_pk") is not None:
30-
# it's a partner program
3150
return self.get_queryset_for_program()
51+
elif self.kwargs.get("user_pk") is not None:
52+
return self.get_queryset_for_user()
3253
else:
3354
return News.objects.none()

news/views.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
from django.contrib.auth import get_user_model
2+
from django.shortcuts import get_object_or_404
13
from rest_framework import generics, status
24
from rest_framework.permissions import IsAuthenticated
35
from rest_framework.response import Response
46

57
from core.serializers import SetViewedSerializer, SetLikedSerializer
68
from core.services import add_view, set_like
9+
from news.mixins import NewsQuerysetMixin
710
from news.models import News
811
from news.pagination import NewsPagination
912
from news.permissions import IsNewsCreatorOrReadOnly
1013
from news.serializers import NewsListSerializer, NewsDetailSerializer
11-
from news.mixins import NewsQuerysetMixin
1214
from projects.models import Project
1315

16+
User = get_user_model()
17+
1418

1519
class NewsList(NewsQuerysetMixin, generics.ListCreateAPIView):
1620
serializer_class = NewsListSerializer
@@ -19,14 +23,20 @@ class NewsList(NewsQuerysetMixin, generics.ListCreateAPIView):
1923

2024
def post(self, request, *args, **kwargs):
2125
if kwargs.get("project_pk"):
22-
project = Project.objects.get(pk=kwargs["project_pk"])
26+
project = get_object_or_404(Project, pk=kwargs["project_pk"])
2327
news = News.objects.add_news(project, **request.data)
2428
return Response(
2529
NewsDetailSerializer(news).data, status=status.HTTP_201_CREATED
2630
)
31+
elif kwargs.get("user_pk"):
32+
user = get_object_or_404(User, pk=kwargs["user_pk"])
33+
news = News.objects.add_news(user, **request.data)
34+
return Response(
35+
NewsDetailSerializer(news).data, status=status.HTTP_201_CREATED
36+
)
2737
else:
28-
# creating partner program news, not implemented yet
29-
raise NotImplementedError()
38+
# creating partner program news, not implemented yet, return 400
39+
return Response(status=status.HTTP_400_BAD_REQUEST)
3040

3141
def get(self, request, *args, **kwargs):
3242
news = self.paginate_queryset(self.get_queryset())

nginx/nginx.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,18 @@ server {
1818
proxy_pass http://grafana:3000;
1919
proxy_set_header Host $host;
2020
}
21+
22+
location @proxy_to_app {
23+
proxy_pass http://web:8000;
24+
25+
proxy_http_version 1.1;
26+
proxy_set_header Upgrade $http_upgrade;
27+
proxy_set_header Connection "upgrade";
28+
29+
proxy_redirect off;
30+
proxy_set_header Host $host;
31+
proxy_set_header X-Real-IP $remote_addr;
32+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33+
proxy_set_header X-Forwarded-Host $server_name;
34+
}
2135
}

users/serializers.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from core.services import get_views_count
66
from core.utils import get_user_online_cache_key
77
from projects.models import Project
8+
from projects.validators import validate_project
89
from .models import CustomUser, Expert, Investor, Member, Mentor, UserAchievement
910

1011

@@ -322,3 +323,38 @@ class PasswordSerializer(serializers.Serializer):
322323

323324
class ResendVerifyEmailSerializer(serializers.Serializer):
324325
email = serializers.EmailField(required=True)
326+
327+
328+
class UserProjectListSerializer(serializers.ModelSerializer):
329+
views_count = serializers.SerializerMethodField(method_name="count_views")
330+
short_description = serializers.SerializerMethodField()
331+
332+
@classmethod
333+
def count_views(cls, project):
334+
return get_views_count(project)
335+
336+
@classmethod
337+
def get_short_description(cls, project):
338+
return project.get_short_description()
339+
340+
class Meta:
341+
model = Project
342+
fields = [
343+
"id",
344+
"name",
345+
"leader",
346+
"short_description",
347+
"image_address",
348+
"industry",
349+
"views_count",
350+
"draft",
351+
]
352+
353+
read_only_fields = ["leader", "views_count"]
354+
355+
def is_valid(self, *, raise_exception=False):
356+
return super().is_valid(raise_exception=raise_exception)
357+
358+
def validate(self, data):
359+
super().validate(data)
360+
return validate_project(data)

users/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.urls import path, re_path, include
22

3+
from news.views import NewsList, NewsDetail, NewsDetailSetViewed, NewsDetailSetLiked
34
from users.views import (
45
AchievementDetail,
56
AchievementList,
@@ -35,6 +36,10 @@
3536
path("users/<int:pk>/", UserDetail.as_view()),
3637
path("users/<int:pk>/set_onboarding_stage/", SetUserOnboardingStage.as_view()),
3738
path("users/<int:pk>/force_verify/", ForceVerifyView.as_view()),
39+
path("users/<int:user_pk>/news/", NewsList.as_view()),
40+
path("users/<int:user_pk>/news/<int:pk>/", NewsDetail.as_view()),
41+
path("users/<int:user_pk>/news/<int:pk>/set_viewed/", NewsDetailSetViewed.as_view()),
42+
path("users/<int:user_pk>/news/<int:pk>/set_liked/", NewsDetailSetLiked.as_view()),
3843
path("users/current/", CurrentUser.as_view()),
3944
# todo: change password view
4045
path("users/current/programs/", CurrentUserPrograms.as_view()),

users/views.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
UserListSerializer,
5151
VerifyEmailSerializer,
5252
ResendVerifyEmailSerializer,
53+
UserProjectListSerializer,
5354
)
5455
from .filters import UserFilter
5556
from .pagination import UsersPagination
@@ -253,18 +254,21 @@ class AchievementDetail(RetrieveUpdateDestroyAPIView):
253254
class UserProjectsList(GenericAPIView):
254255
permission_classes = [IsAuthenticated]
255256
pagination_class = ProjectsPagination
256-
serializer_class = ProjectListSerializer
257+
serializer_class = UserProjectListSerializer
257258

258259
def get(self, request):
259-
queryset = Project.objects.get_user_projects_for_list_view().filter(
260+
self.queryset = Project.objects.get_user_projects_for_list_view().filter(
260261
Q(leader_id=self.request.user.id) | Q(collaborator__user=self.request.user)
261262
)
262263

263-
page = self.paginate_queryset(queryset)
264+
page = self.paginate_queryset(self.queryset)
264265
if page is not None:
265266
serializer = self.get_serializer(page, many=True)
266267
return self.get_paginated_response(serializer.data)
267-
return Response(serializer.data, status=status.HTTP_200_OK)
268+
return Response(
269+
{"detail": "Unable to return paginated list"},
270+
status=status.HTTP_400_BAD_REQUEST,
271+
)
268272

269273

270274
class LogoutView(APIView):

0 commit comments

Comments
 (0)