Skip to content

Commit 8c93cc8

Browse files
authored
Merge pull request #299 from PROCOLLAB-github/dev
added correct dates to feed
2 parents da12c13 + 51f98d1 commit 8c93cc8

File tree

15 files changed

+182
-282
lines changed

15 files changed

+182
-282
lines changed

feed/apps.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
class FeedConfig(AppConfig):
55
default_auto_field = "django.db.models.BigAutoField"
66
name = "feed"
7+
8+
def ready(self):
9+
import feed.signals # noqa: F401

feed/constants.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

feed/helpers.py

Lines changed: 0 additions & 151 deletions
This file was deleted.

feed/pagination.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,7 @@
11
from rest_framework import pagination
2-
from rest_framework.request import Request
3-
4-
from feed.constants import SupportedQuerySet
52

63

74
class FeedPagination(pagination.LimitOffsetPagination):
85
default_limit = 10
96
limit_query_param = "limit"
107
offset_query_param = "offset"
11-
12-
def custom_paginate_queryset(
13-
self, queryset: SupportedQuerySet, request: Request, count: int, view=None
14-
) -> dict:
15-
self.limit = self.get_limit(request)
16-
if self.limit is None:
17-
return None
18-
19-
self.count = count
20-
self.offset = self.get_offset(request)
21-
self.request = request
22-
if self.count > self.limit and self.template is not None:
23-
self.display_page_controls = True
24-
25-
if self.count == 0 or self.offset > self.count:
26-
return {"queryset_ready": [], "count": self.count}
27-
28-
queryset_ready = queryset[self.offset : self.offset + self.limit] # noqa: E203
29-
return {
30-
"queryset_ready": queryset_ready,
31-
"count": self.count,
32-
}

feed/signals.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from django.contrib.contenttypes.models import ContentType
2+
from django.db.models.signals import post_save
3+
from django.dispatch import receiver
4+
5+
from news.models import News
6+
7+
8+
from vacancy.models import Vacancy
9+
10+
11+
@receiver(post_save, sender=Vacancy)
12+
def create_news_on_save(sender, instance, created, **kwargs):
13+
if created:
14+
content_type = ContentType.objects.filter(model="vacancy").first()
15+
news_instance, created = News.objects.get_or_create(
16+
content_type=content_type, object_id=instance.id
17+
)

feed/urls.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from django.urls import path
22

3-
from feed.views import FeedList
3+
from feed.views import NewSimpleFeed, DevScript
44

55
app_name = "feed"
66

77
urlpatterns = [
8-
path("", FeedList.as_view()),
8+
path("", NewSimpleFeed.as_view()),
9+
path("dev-needs-script", DevScript.as_view()),
910
]

feed/views.py

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,83 @@
1-
from drf_yasg import openapi
2-
from drf_yasg.utils import swagger_auto_schema
3-
from rest_framework import status
4-
from rest_framework.request import Request
1+
from django.contrib.contenttypes.models import ContentType
2+
from django.db.models import Q
3+
from rest_framework.generics import CreateAPIView
54
from rest_framework.response import Response
65
from rest_framework.views import APIView
76

8-
from feed.constants import SupportedModel, SupportedQuerySet, FeedItemType, model_mapping
9-
from feed.helpers import collect_querysets, paginate_serialize_feed, add_pagination
107
from feed.pagination import FeedPagination
118

9+
from news.models import News
10+
from news.serializers import NewsFeedListSerializer
11+
from projects.models import Project
12+
from vacancy.models import Vacancy
1213

13-
class FeedList(APIView):
14-
pagination_class = FeedPagination
1514

16-
@swagger_auto_schema(
17-
responses={
18-
200: openapi.Response(
19-
description="List of some news: new projects, vacancies, project, users and program news",
20-
schema=openapi.Schema(
21-
type=openapi.TYPE_ARRAY,
22-
items=openapi.Schema(
23-
type=openapi.TYPE_OBJECT,
24-
description="Feed item",
25-
properties={
26-
"type": openapi.TYPE_STRING,
27-
"content": openapi.TYPE_OBJECT,
28-
},
29-
),
30-
),
31-
)
32-
}
33-
)
34-
def get(self, request: Request, *args, **kwargs) -> Response:
35-
prepared_data, sum_pages = self.paginate_serialize_data(
36-
self.get_response_data(self.get_request_data())
37-
)
38-
for obj in prepared_data:
39-
obj["type_model"] = obj["type_model"].lower()
40-
return Response(
41-
status=status.HTTP_200_OK,
42-
data=add_pagination(prepared_data, sum_pages),
43-
)
15+
class NewSimpleFeed(APIView):
16+
serializator_class = NewsFeedListSerializer
17+
pagination_class = FeedPagination
4418

45-
def get_request_data(self) -> list[SupportedModel]:
19+
def get_filter_data(self):
4620
filter_queries = self.request.query_params.get("type")
4721
filter_queries = filter_queries if filter_queries else "" # existence check
4822

49-
models = [
50-
model_mapping[model_name]
51-
for model_name in model_mapping.keys()
52-
if model_name.lower() in filter_queries
53-
]
54-
return models
23+
news_types = filter_queries.split("|")
24+
if "news" in news_types:
25+
news_types.append("customuser")
26+
return news_types
5527

56-
def get_response_data(
57-
self, models: list[SupportedModel]
58-
) -> dict[FeedItemType, SupportedQuerySet]:
59-
return {model.__name__: collect_querysets(model) for model in models}
28+
def get_queryset(self):
29+
filters = self.get_filter_data()
30+
queryset = (
31+
News.objects.select_related("content_type")
32+
.prefetch_related("content_object", "files")
33+
.filter(content_type__model__in=filters)
34+
.order_by("-datetime_created")
35+
)
36+
# временное удаление постов для проектов с текстом
37+
return queryset.exclude(~Q(text=""), content_type__model="project")
6038

61-
def paginate_serialize_data(
62-
self, get_model_data: dict[FeedItemType, SupportedQuerySet]
63-
) -> tuple[list[dict], int]:
39+
def get(self, *args, **kwargs):
6440
paginator = self.pagination_class()
65-
return paginate_serialize_feed(get_model_data, paginator, self.request, self)
41+
paginated_data = paginator.paginate_queryset(self.get_queryset(), self.request)
42+
serializer = NewsFeedListSerializer(paginated_data, many=True)
43+
44+
new_data = []
45+
# временная подстройка данных под фронт
46+
for data in serializer.data:
47+
if data["type_model"] in ["project", "vacancy", None]:
48+
fomated_data = {
49+
"type_model": data["type_model"],
50+
"content": data["content_object"],
51+
}
52+
elif data["type_model"] == "news":
53+
del data["type_model"]
54+
fomated_data = {"type_model": "news", "content": data}
55+
new_data.append(fomated_data)
56+
57+
return paginator.get_paginated_response(new_data)
58+
59+
60+
class DevScript(CreateAPIView):
61+
def create(self, request):
62+
content_type = ContentType.objects.filter(model="project").first()
63+
for project in Project.objects.filter(draft=False):
64+
if not News.objects.filter(
65+
content_type=content_type, object_id=project.id
66+
).exists():
67+
News.objects.create(
68+
content_type=content_type,
69+
object_id=project.id,
70+
datetime_created=project.datetime_created,
71+
)
72+
73+
content_type = ContentType.objects.filter(model="vacancy").first()
74+
for vacancy in Vacancy.objects.filter(is_active=True):
75+
if not News.objects.filter(
76+
content_type=content_type, object_id=vacancy.id
77+
).exists():
78+
News.objects.create(
79+
content_type=content_type,
80+
object_id=vacancy.id,
81+
datetime_created=vacancy.datetime_created,
82+
)
83+
return Response({"status": "success"}, status=201)

0 commit comments

Comments
 (0)