Skip to content

Commit f0339f5

Browse files
committed
Merge branch 'dev' of https://github.com/PROCOLLAB-github/api into dev
2 parents 7645ebf + 5855659 commit f0339f5

10 files changed

Lines changed: 176 additions & 10 deletions

File tree

chats/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def get_chat(cls, user1, user2) -> "DirectChat":
160160
def get_last_messages(self, message_count):
161161
return self.messages.order_by("-created_at")[:message_count]
162162

163-
def get_other_user(self, user):
163+
def get_other_user(self, user) -> User:
164164
return self.users.exclude(pk=user.pk).first()
165165

166166
@classmethod

chats/serializers.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,28 @@
1313
class DirectChatListSerializer(serializers.ModelSerializer):
1414
last_message = serializers.SerializerMethodField()
1515
opponent = serializers.SerializerMethodField()
16+
name = serializers.SerializerMethodField(read_only=True)
17+
image_address = serializers.SerializerMethodField(read_only=True)
1618

1719
def get_opponent(self, chat: DirectChat):
1820
user = self.context.get("opponent")
1921
return UserDetailSerializer(user).data
2022

23+
def get_name(self, chat: DirectChat):
24+
user = self.context.get("opponent")
25+
return user.get_full_name()
26+
27+
def get_image_address(self, chat: DirectChat):
28+
user = self.context.get("opponent")
29+
return user.avatar
30+
2131
@classmethod
2232
def get_last_message(cls, chat: DirectChat):
2333
return DirectChatMessageListSerializer(chat.get_last_message()).data
2434

2535
class Meta:
2636
model = DirectChat
27-
fields = [
28-
"id",
29-
"opponent",
30-
"last_message",
31-
]
37+
fields = ["id", "opponent", "last_message", "name", "image_address"]
3238

3339

3440
class DirectChatDetailSerializer(serializers.ModelSerializer):
@@ -48,14 +54,24 @@ class Meta:
4854

4955
class ProjectChatListSerializer(serializers.ModelSerializer):
5056
last_message = serializers.SerializerMethodField(read_only=True)
57+
name = serializers.SerializerMethodField(read_only=True)
58+
image_address = serializers.SerializerMethodField(read_only=True)
59+
60+
@classmethod
61+
def get_image_address(cls, chat: ProjectChat):
62+
return chat.project.image_address
63+
64+
@classmethod
65+
def get_name(cls, chat: ProjectChat):
66+
return chat.project.name
5167

5268
@classmethod
5369
def get_last_message(cls, chat: ProjectChat):
5470
return ProjectChatMessageListSerializer(chat.get_last_message()).data
5571

5672
class Meta:
5773
model = ProjectChat
58-
fields = ["id", "project", "last_message"]
74+
fields = ["id", "project", "last_message", "image_address", "name"]
5975

6076

6177
class ProjectChatDetailSerializer(serializers.ModelSerializer):

files/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ def __str__(self):
3434
class Meta:
3535
verbose_name = "Файл"
3636
verbose_name_plural = "Файлы"
37+
ordering = ["datetime_uploaded"]

nginx/nginx.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ server {
1010
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
1111
proxy_set_header Host $host;
1212
proxy_redirect off;
13+
proxy_set_header Connection "upgrade";
14+
proxy_set_header Upgrade $http_upgrade;
1315
}
1416

1517
location /grafana {

partner_programs/admin.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import tablib
2+
13
from django.contrib import admin
4+
from django.http import HttpResponse
5+
from django.urls import path
6+
from django.utils import timezone
27

38
from partner_programs.models import PartnerProgram, PartnerProgramUserProfile
49

@@ -28,10 +33,76 @@ class PartnerProgramAdmin(admin.ModelAdmin):
2833

2934
filter_horizontal = ("users",)
3035
date_hierarchy = "datetime_started"
36+
change_form_template = "partner_programs/admin/programs_change_form.html"
37+
38+
def get_urls(self):
39+
default_urls = super(PartnerProgramAdmin, self).get_urls()
40+
custom_urls = [
41+
path(
42+
"export/<int:object_id>/",
43+
self.admin_site.admin_view(self.get_export_file_view),
44+
name="export_profiles",
45+
)
46+
]
47+
return custom_urls + default_urls
48+
49+
def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
50+
extra_context = {"object_id": int(object_id)}
51+
res = super(PartnerProgramAdmin, self).changeform_view(
52+
request, object_id, extra_context=extra_context
53+
)
54+
return res
55+
56+
def get_export_file_view(self, request, object_id):
57+
program = PartnerProgram.objects.get(pk=object_id)
58+
return self.get_export_file(program)
59+
60+
def get_export_file(self, partner_program: PartnerProgram):
61+
json_schema = partner_program.data_schema
62+
profiles = PartnerProgramUserProfile.objects.filter(
63+
partner_program=partner_program
64+
)
65+
to_delete_from_json_scheme = []
66+
column_names = ["Имя", "Фамилия", "Отчество", "Почта", "Дата рождения"]
67+
for field_key in json_schema:
68+
if "name" not in json_schema[field_key]:
69+
to_delete_from_json_scheme.append(field_key)
70+
else:
71+
column_names.append(json_schema[field_key]["name"])
72+
73+
for field_key in to_delete_from_json_scheme:
74+
del json_schema[field_key]
75+
76+
response_data = tablib.Dataset(headers=column_names)
77+
for profile in profiles:
78+
row = [
79+
profile.user.first_name,
80+
profile.user.last_name,
81+
profile.user.patronymic,
82+
profile.user.email,
83+
str(profile.user.birthday),
84+
]
85+
86+
json_data = profile.partner_program_data
87+
for key in json_schema:
88+
row.append(json_data.get(key, ""))
89+
response_data.append(row)
90+
91+
binary_data = response_data.export("xlsx")
92+
file_name = (
93+
f'{partner_program.name} {timezone.now().strftime("%d-%m-%Y %H:%M:%S")}'
94+
)
95+
response = HttpResponse(
96+
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
97+
headers={"Content-Disposition": f'attachment; filename="{file_name}.xlsx"'},
98+
)
99+
response.write(binary_data)
100+
return response
31101

32102

33103
@admin.register(PartnerProgramUserProfile)
34104
class PartnerProgramUserProfileAdmin(admin.ModelAdmin):
105+
35106
list_display = (
36107
"id",
37108
"user",

poetry.lock

Lines changed: 50 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

projects/admin.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
from django.contrib import admin
22

3-
from projects.models import DefaultProjectCover, Project, Achievement, Collaborator, ProjectLink, ProjectNews
3+
from projects.models import (
4+
DefaultProjectCover,
5+
Project,
6+
Achievement,
7+
Collaborator,
8+
ProjectLink,
9+
ProjectNews,
10+
)
411

512

613
@admin.register(Project)

projects/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class Meta:
130130
"views_count",
131131
"likes_count",
132132
"cover",
133-
"partner_programs_tags"
133+
"partner_programs_tags",
134134
]
135135
read_only_fields = [
136136
"leader",

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ coreapi = "^2.3.3"
5959
webp = "^0.1.6"
6060
django-prometheus = "^2.3.1"
6161
loguru = "^0.7.1"
62+
tablib = {extras = ["xlsx"], version = "^3.5.0"}
6263

6364

6465
[build-system]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{% extends "admin/change_form.html" %}
2+
{% load i18n %}
3+
4+
{% block submit_buttons_bottom %}
5+
6+
7+
{{ block.super }}
8+
<div class="submit-row">
9+
<input type="button" class="export-btn" value="Экспорт" onclick="export_profiles()"/>
10+
</div>
11+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
12+
<script>
13+
function export_profiles(){
14+
window.open("{% url 'admin:export_profiles' object_id %}", '_blank').focus()
15+
}
16+
</script>
17+
18+
{% endblock %}
19+

0 commit comments

Comments
 (0)