Skip to content

Commit 1ab3896

Browse files
committed
Added links field for projects
Created `ProjectLink` model
1 parent 9299a39 commit 1ab3896

8 files changed

Lines changed: 138 additions & 20 deletions

File tree

projects/admin.py

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

3-
from projects.models import Project, Achievement, Collaborator
3+
from projects.models import Project, Achievement, Collaborator, ProjectLink
44

55

66
@admin.register(Project)
@@ -21,6 +21,12 @@ class AchievementAdmin(admin.ModelAdmin):
2121
list_display = ("id", "title", "status", "project")
2222

2323

24+
@admin.register(ProjectLink)
25+
class ProjectLinkAdmin(admin.ModelAdmin):
26+
list_display = ("id", "link", "project")
27+
list_display_links = ("id", "link", "project")
28+
29+
2430
@admin.register(Collaborator)
2531
class CollaboratorAdmin(admin.ModelAdmin):
2632
list_display = (

projects/helpers.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django.contrib.auth import get_user_model
44

55
from projects.constants import RECOMMENDATIONS_COUNT
6-
from projects.models import Project
6+
from projects.models import Project, ProjectLink, Achievement
77

88
User = get_user_model()
99

@@ -33,3 +33,54 @@ def get_recommended_users(project: Project) -> list[User]:
3333
)
3434

3535
return sampled_recommended_users
36+
37+
38+
def check_related_fields_update(data, pk):
39+
"""
40+
Check if achievements or links were updated and update them.
41+
"""
42+
43+
if data.get("achievements") is not None:
44+
update_achievements(data.get("achievements"), pk)
45+
46+
if data.get("links") is not None:
47+
update_links(data.get("links"), pk)
48+
49+
50+
def update_achievements(achievements, pk):
51+
"""
52+
Bootleg version of updating achievements via project
53+
"""
54+
55+
# delete all old achievements
56+
Achievement.objects.filter(project_id=pk).delete()
57+
# create new achievements
58+
Achievement.objects.bulk_create(
59+
[
60+
Achievement(
61+
project_id=pk,
62+
title=achievement.get("title"),
63+
status=achievement.get("status"),
64+
)
65+
for achievement in achievements
66+
]
67+
)
68+
69+
70+
def update_links(links, pk):
71+
"""
72+
Bootleg version of updating links via project
73+
"""
74+
75+
# delete all old links
76+
ProjectLink.objects.filter(project_id=pk).delete()
77+
# create new links
78+
ProjectLink.objects.bulk_create(
79+
[
80+
ProjectLink(
81+
project_id=pk,
82+
link=link,
83+
)
84+
for link in links
85+
]
86+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Generated by Django 4.2 on 2023-05-16 21:02
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
("projects", "0011_project_views_count"),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name="ProjectLink",
16+
fields=[
17+
(
18+
"id",
19+
models.BigAutoField(
20+
auto_created=True,
21+
primary_key=True,
22+
serialize=False,
23+
verbose_name="ID",
24+
),
25+
),
26+
("link", models.URLField()),
27+
(
28+
"project",
29+
models.ForeignKey(
30+
on_delete=django.db.models.deletion.CASCADE,
31+
related_name="links",
32+
to="projects.project",
33+
),
34+
),
35+
],
36+
options={
37+
"verbose_name": "Ссылка проекта",
38+
"verbose_name_plural": "Ссылки проектов",
39+
"unique_together": {("project", "link")},
40+
},
41+
),
42+
]

projects/models.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,31 @@ class Meta:
9595
verbose_name_plural = "Проекты"
9696

9797

98+
class ProjectLink(models.Model):
99+
"""
100+
Project link model
101+
102+
Attributes:
103+
project: A ForeignKey referring to the Project model.
104+
link: A URLField link to the project.
105+
"""
106+
107+
project = models.ForeignKey(
108+
Project,
109+
on_delete=models.CASCADE,
110+
related_name="links",
111+
)
112+
link = models.URLField(null=False, blank=False)
113+
114+
def __str__(self):
115+
return f"ProjectLink<{self.id}> - {self.project.name}"
116+
117+
class Meta:
118+
verbose_name = "Ссылка проекта"
119+
verbose_name_plural = "Ссылки проектов"
120+
unique_together = ("project", "link")
121+
122+
98123
class Achievement(models.Model):
99124
"""
100125
Achievement model

projects/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ class ProjectDetailSerializer(serializers.ModelSerializer):
6767
short_description = serializers.SerializerMethodField()
6868
industry_id = serializers.IntegerField(required=False)
6969
likes_count = serializers.SerializerMethodField(method_name="count_likes")
70+
links = serializers.SerializerMethodField()
71+
72+
@classmethod
73+
def get_links(cls, project):
74+
return [link.link for link in project.links.all()]
7075

7176
def validate(self, data):
7277
super().validate(data)
@@ -92,6 +97,7 @@ class Meta:
9297
"description",
9398
"short_description",
9499
"achievements",
100+
"links",
95101
"region",
96102
"step",
97103
"industry",

projects/views.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from core.permissions import IsStaffOrReadOnly
1010
from projects.filters import ProjectFilter
1111
from projects.constants import VERBOSE_STEPS
12-
from projects.helpers import get_recommended_users
12+
from projects.helpers import get_recommended_users, check_related_fields_update
1313
from projects.models import Project, Achievement
1414
from projects.permissions import (
1515
IsProjectLeaderOrReadOnlyForNonDrafts,
@@ -91,23 +91,11 @@ def retrieve(self, request, *args, **kwargs):
9191
return Response(serializer.data)
9292

9393
def put(self, request, pk, **kwargs):
94-
# bootleg version of updating achievements via project
95-
if request.data.get("achievements") is not None:
96-
achievements = request.data.get("achievements")
97-
# delete all old achievements
98-
Achievement.objects.filter(project_id=pk).delete()
99-
# create new achievements
100-
Achievement.objects.bulk_create(
101-
[
102-
Achievement(
103-
project_id=pk,
104-
title=achievement.get("title"),
105-
status=achievement.get("status"),
106-
)
107-
for achievement in achievements
108-
]
109-
)
94+
check_related_fields_update(request.data, pk)
95+
return super(ProjectDetail, self).put(request, pk)
11096

97+
def patch(self, request, pk, **kwargs):
98+
check_related_fields_update(request.data, pk)
11199
return super(ProjectDetail, self).put(request, pk)
112100

113101

users/admin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,4 @@ class UserAchievementAdmin(admin.ModelAdmin):
149149
@admin.register(UserLink)
150150
class UserLinkAdmin(admin.ModelAdmin):
151151
list_display = ("id", "user", "link")
152+
list_display_links = ("id", "user", "link")

users/views.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ def put(self, request, pk):
123123
@transaction.atomic
124124
def patch(self, request, pk):
125125
check_related_fields_update(request.data, pk)
126-
127126
return super().patch(request, pk)
128127

129128

0 commit comments

Comments
 (0)