Skip to content

Commit d217a56

Browse files
authored
Merge pull request #323 from PROCOLLAB-github/flexivanov237-pro-209
Flexivanov237 pro 209
2 parents 29405ef + 8c6672d commit d217a56

8 files changed

Lines changed: 1559 additions & 1228 deletions

File tree

feed/mapping.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from partner_programs.serializers import PartnerProgramListSerializer
2+
from projects.models import Project
3+
from projects.serializers import ProjectListSerializer
4+
from users.models import CustomUser
5+
from users.serializers import UserFeedSerializer
6+
from vacancy.models import Vacancy
7+
from vacancy.serializers import VacancyDetailSerializer
8+
9+
CONTENT_OBJECT_MAPPING: dict[str, str | None] = {
10+
Project.__name__.lower(): "project",
11+
CustomUser.__name__.lower(): "news",
12+
"partnerprogram": None,
13+
Vacancy.__name__.lower(): "vacancy",
14+
}
15+
16+
CONTENT_OBJECT_SERIALIZER_MAPPING: dict = {
17+
Project.__name__.lower(): ProjectListSerializer,
18+
CustomUser.__name__.lower(): UserFeedSerializer,
19+
"partnerprogram": PartnerProgramListSerializer,
20+
Vacancy.__name__.lower(): VacancyDetailSerializer,
21+
}

feed/views.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from django.contrib.contenttypes.models import ContentType
2-
from django.db.models import Q
32
from rest_framework.generics import CreateAPIView
43
from rest_framework.response import Response
54
from rest_framework.views import APIView
@@ -33,13 +32,14 @@ def get_queryset(self):
3332
.filter(content_type__model__in=filters)
3433
.order_by("-datetime_created")
3534
)
36-
# временное удаление постов для проектов с текстом
37-
return queryset.exclude(~Q(text=""), content_type__model="project")
35+
return queryset
3836

3937
def get(self, *args, **kwargs):
4038
paginator = self.pagination_class()
4139
paginated_data = paginator.paginate_queryset(self.get_queryset(), self.request)
42-
serializer = NewsFeedListSerializer(paginated_data, many=True)
40+
serializer = NewsFeedListSerializer(
41+
paginated_data, context={"user": self.request.user}, many=True
42+
)
4343

4444
new_data = []
4545
# временная подстройка данных под фронт

news/serializers.py

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
from django.contrib.auth import get_user_model
2-
from django.forms import model_to_dict
32
from rest_framework import serializers
43

54
from core.services import is_fan, get_likes_count, get_views_count
5+
from feed.mapping import CONTENT_OBJECT_MAPPING, CONTENT_OBJECT_SERIALIZER_MAPPING
66
from files.serializers import UserFileSerializer
77
from news.mapping import NewsMapping
88
from news.models import News
99

10-
from partner_programs.serializers import PartnerProgramListSerializer
1110
from projects.models import Project
12-
from projects.serializers import ProjectListSerializer
1311
from users.models import CustomUser
14-
from users.serializers import UserFeedSerializer
15-
from vacancy.models import Vacancy
16-
from vacancy.serializers import VacancyDetailSerializer
1712

1813
User = get_user_model()
1914

@@ -78,33 +73,18 @@ class NewsFeedListSerializer(serializers.ModelSerializer):
7873
content_object = serializers.SerializerMethodField()
7974
type_model = serializers.SerializerMethodField()
8075

81-
def get_type_model(self, obj):
82-
if obj.content_type.model == Project.__name__.lower():
83-
return "project"
84-
elif obj.content_type.model == CustomUser.__name__.lower():
76+
def get_type_model(self, obj) -> str:
77+
model_type = CONTENT_OBJECT_MAPPING[obj.content_type.model]
78+
if obj.text != "" and model_type == "project":
8579
return "news"
86-
elif obj.content_type.model == "partnerprogram":
87-
return None
88-
elif obj.content_type.model == Vacancy.__name__.lower():
89-
return "vacancy"
90-
91-
def get_content_object(self, obj):
92-
if obj.content_type.model == Project.__name__.lower():
93-
serialized_obj = ProjectListSerializer(instance=obj.content_object, data={})
94-
serialized_obj.is_valid()
95-
return serialized_obj.data
96-
elif obj.content_type.model == CustomUser.__name__.lower():
97-
serialized_obj = UserFeedSerializer(
98-
instance=obj.content_object, data=model_to_dict(obj.content_object)
99-
)
100-
serialized_obj.is_valid()
101-
return serialized_obj.data
102-
elif obj.content_type.model == "partnerprogram":
103-
serialized_obj = PartnerProgramListSerializer(obj.content_object)
104-
return serialized_obj.data
105-
elif obj.content_type.model == Vacancy.__name__.lower():
106-
serialized_obj = VacancyDetailSerializer(obj.content_object)
107-
return serialized_obj.data
80+
return model_type
81+
82+
def get_content_object(self, obj) -> dict:
83+
type_model = obj.content_type.model
84+
if obj.text != "" and self.get_type_model(obj) == "project":
85+
type_model = "news"
86+
serializer = CONTENT_OBJECT_SERIALIZER_MAPPING[type_model](obj.content_object)
87+
return serializer.data
10888

10989
def get_views_count(self, obj):
11090
return get_views_count(obj)
@@ -115,6 +95,8 @@ def get_likes_count(self, obj):
11595
def get_name(self, obj):
11696
if obj.content_type.model == CustomUser.__name__.lower():
11797
return f"{obj.content_object.first_name} {obj.content_object.last_name}"
98+
elif obj.text != "" and obj.content_type.model == Project.__name__.lower():
99+
return f"{obj.content_object.name}"
118100

119101
def get_image_address(self, obj):
120102
return NewsMapping.get_image_address(obj.content_object)

partner_programs/admin.py

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1+
import pandas as pd
12
import tablib
23
import re
34
from django.contrib import admin
45
from django.http import HttpResponse
56
from django.urls import path
67
from django.utils import timezone
8+
79
from mailing.views import MailingTemplateRender
810
from partner_programs.models import PartnerProgram, PartnerProgramUserProfile
11+
from project_rates.models import Criteria, ProjectScore
12+
from projects.models import Project
13+
from users.models import Expert
914

1015

1116
@admin.register(PartnerProgram)
1217
class PartnerProgramAdmin(admin.ModelAdmin):
13-
list_display = (
14-
"id",
15-
"name",
16-
"tag",
17-
"city",
18-
"datetime_created",
19-
)
18+
list_display = ("id", "name", "tag", "city", "datetime_created")
2019
list_display_links = (
2120
"id",
2221
"name",
@@ -48,6 +47,11 @@ def get_urls(self):
4847
self.admin_site.admin_view(self.mailing),
4948
name="partner_programs_mailing",
5049
),
50+
path(
51+
"export-rates/<int:object_id>/",
52+
self.admin_site.admin_view(self.get_export_rates_view),
53+
name="partner_programs_export_rates",
54+
),
5155
]
5256
return custom_urls + default_urls
5357

@@ -126,6 +130,87 @@ def get_export_file(self, partner_program: PartnerProgram):
126130
response.write(binary_data)
127131
return response
128132

133+
def get_export_rates_view(self, request, object_id):
134+
criterias = Criteria.objects.filter(partner_program__id=object_id).select_related(
135+
"partner_program"
136+
)
137+
experts = Expert.objects.filter(programs=object_id).select_related("user")
138+
scores = ProjectScore.objects.filter(criteria__in=criterias)
139+
projects = Project.objects.filter(scores__in=scores)
140+
return self.get_export_rates(criterias, experts, scores, projects)
141+
142+
def get_export_rates(self, criterias, experts, scores, projects):
143+
col_names = list(
144+
criterias.exclude(name="Комментарий").values_list("name", flat=True)
145+
)
146+
147+
expert_names = [
148+
expert.user.first_name + " " + expert.user.last_name for expert in experts
149+
]
150+
151+
all_projects_data = []
152+
for project in projects:
153+
project_data = [[project.name, *col_names, "Комментарий"]]
154+
155+
for expert, expert_name in zip(experts, expert_names):
156+
single_rate_data = [expert_name]
157+
158+
scores_of_expert = []
159+
criterias_to_check = criterias.exclude(name="Комментарий")
160+
for criteria in criterias_to_check:
161+
checking_score = (
162+
scores.filter(
163+
criteria=criteria,
164+
user__first_name=expert.user.first_name,
165+
user__last_name=expert.user.last_name,
166+
project__name=project.name,
167+
)
168+
.exclude(criteria__name="Комментарий")
169+
.first()
170+
)
171+
if not checking_score:
172+
scores_of_expert.append("")
173+
else:
174+
scores_of_expert.append(checking_score.value)
175+
176+
commentary = scores.filter(
177+
user__first_name=expert.user.first_name,
178+
user__last_name=expert.user.last_name,
179+
criteria__name="Комментарий",
180+
project__name=project.name,
181+
).first()
182+
commentary = [commentary.value] if commentary else [""]
183+
184+
scores_of_expert += commentary
185+
186+
single_rate_data += scores_of_expert
187+
188+
project_data.append(single_rate_data)
189+
all_projects_data.append(project_data)
190+
191+
dataframed_projects_data = [
192+
pd.DataFrame(project_data) for project_data in all_projects_data
193+
]
194+
with pd.ExcelWriter("output.xlsx") as writer:
195+
for df, pr_data in zip(dataframed_projects_data, all_projects_data):
196+
df.to_excel(writer, sheet_name=pr_data[0][0], index=False)
197+
198+
with open("output.xlsx", "rb") as f:
199+
binary_data = f.read()
200+
201+
# Формирование HTTP-ответа
202+
file_name = (
203+
f'{criterias.first().partner_program.name}_оценки {timezone.now().strftime("%d-%m-%Y %H:%M:%S")}'
204+
f".xlsx"
205+
)
206+
response = HttpResponse(
207+
binary_data,
208+
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
209+
)
210+
response["Content-Disposition"] = f'attachment; filename="{file_name}"'
211+
212+
return response
213+
129214

130215
@admin.register(PartnerProgramUserProfile)
131216
class PartnerProgramUserProfileAdmin(admin.ModelAdmin):

0 commit comments

Comments
 (0)