Skip to content

Commit 9299a39

Browse files
committed
Added links field for user
Created `UserLink` model
1 parent 5329c76 commit 9299a39

6 files changed

Lines changed: 130 additions & 9 deletions

File tree

users/admin.py

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

44
from .helpers import send_verification_completed_email
5-
from .models import CustomUser, UserAchievement, Member, Mentor, Expert, Investor
5+
from .models import (
6+
CustomUser,
7+
UserAchievement,
8+
Member,
9+
Mentor,
10+
Expert,
11+
Investor,
12+
UserLink,
13+
)
614

715

816
@admin.register(CustomUser)
@@ -136,3 +144,8 @@ def save_model(self, request, obj, form, change):
136144
@admin.register(UserAchievement)
137145
class UserAchievementAdmin(admin.ModelAdmin):
138146
list_display = ("id", "title", "status", "user")
147+
148+
149+
@admin.register(UserLink)
150+
class UserLinkAdmin(admin.ModelAdmin):
151+
list_display = ("id", "user", "link")

users/helpers.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from core.utils import Email
77
from users.constants import PROTOCOL
8-
from users.models import UserAchievement
8+
from users.models import UserAchievement, UserLink
99

1010
User = get_user_model()
1111

@@ -91,7 +91,23 @@ def send_verification_completed_email(user: User):
9191
Email.send_email(data)
9292

9393

94+
def check_related_fields_update(data, pk):
95+
"""
96+
Check if achievements or links were updated and update them.
97+
"""
98+
99+
if data.get("achievements") is not None:
100+
update_achievements(data.get("achievements"), pk)
101+
102+
if data.get("links") is not None:
103+
update_links(data.get("links"), pk)
104+
105+
94106
def update_achievements(achievements, pk):
107+
"""
108+
Bootleg version of updating achievements via user
109+
"""
110+
95111
# delete all old achievements
96112
UserAchievement.objects.filter(user_id=pk).delete()
97113
# create new achievements
@@ -105,3 +121,22 @@ def update_achievements(achievements, pk):
105121
for achievement in achievements
106122
]
107123
)
124+
125+
126+
def update_links(links, pk):
127+
"""
128+
Bootleg version of updating links via user
129+
"""
130+
131+
# delete all old links
132+
UserLink.objects.filter(user_id=pk).delete()
133+
# create new links
134+
UserLink.objects.bulk_create(
135+
[
136+
UserLink(
137+
user_id=pk,
138+
link=link,
139+
)
140+
for link in links
141+
]
142+
)

users/migrations/0036_userlink.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Generated by Django 4.2 on 2023-05-16 19:48
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
("users", "0035_alter_customuser_onboarding_stage"),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name="UserLink",
17+
fields=[
18+
(
19+
"id",
20+
models.BigAutoField(
21+
auto_created=True,
22+
primary_key=True,
23+
serialize=False,
24+
verbose_name="ID",
25+
),
26+
),
27+
("link", models.URLField()),
28+
(
29+
"user",
30+
models.ForeignKey(
31+
on_delete=django.db.models.deletion.CASCADE,
32+
related_name="links",
33+
to=settings.AUTH_USER_MODEL,
34+
),
35+
),
36+
],
37+
options={
38+
"verbose_name": "Ссылка пользователя",
39+
"verbose_name_plural": "Ссылки пользователей",
40+
"unique_together": {("user", "link")},
41+
},
42+
),
43+
]

users/models.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,30 @@ def create_or_update_user_types(sender, instance, created, **kwargs):
324324
Expert.objects.create(user=instance)
325325
elif instance.user_type == CustomUser.INVESTOR:
326326
Investor.objects.create(user=instance)
327+
328+
329+
class UserLink(models.Model):
330+
"""
331+
UserLink model
332+
333+
Represents the user's link to some resource.
334+
335+
Attributes:
336+
user: ForeignKey instance of the CustomUser model.
337+
link: URLField instance of the user's link to some resource.
338+
"""
339+
340+
user = models.ForeignKey(
341+
CustomUser,
342+
on_delete=models.CASCADE,
343+
related_name="links",
344+
)
345+
link = models.URLField(null=False, blank=False)
346+
347+
def __str__(self):
348+
return f"UserLink<{self.id}> - {self.user.first_name} {self.user.last_name}"
349+
350+
class Meta:
351+
verbose_name = "Ссылка пользователя"
352+
verbose_name_plural = "Ссылки пользователей"
353+
unique_together = ("user", "link")

users/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ class UserDetailSerializer(serializers.ModelSerializer):
8383
mentor = MentorSerializer(required=False)
8484
achievements = AchievementListSerializer(required=False, many=True)
8585
key_skills = KeySkillsField(required=False)
86+
links = serializers.SerializerMethodField()
8687
is_online = serializers.SerializerMethodField()
8788

89+
@classmethod
90+
def get_links(cls, user: CustomUser):
91+
return [user_link.link for user_link in user.links.all()]
92+
8893
@classmethod
8994
def get_is_online(cls, user: CustomUser):
9095
cache_key = get_user_online_cache_key(user)
@@ -106,6 +111,7 @@ class Meta:
106111
"organization",
107112
"about_me",
108113
"avatar",
114+
"links",
109115
"city",
110116
"is_active",
111117
"is_online",

users/views.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from users.helpers import (
3030
reset_email,
3131
verify_email,
32-
update_achievements,
32+
check_related_fields_update,
3333
)
3434
from users.constants import (
3535
VERBOSE_ROLE_TYPES,
@@ -117,16 +117,13 @@ class UserDetail(RetrieveUpdateDestroyAPIView):
117117

118118
@transaction.atomic
119119
def put(self, request, pk):
120-
# bootleg version of updating achievements via user
121-
if request.data.get("achievements") is not None:
122-
update_achievements(request.data.get("achievements"), pk)
120+
check_related_fields_update(request.data, pk)
123121
return super().put(request, pk)
124122

125123
@transaction.atomic
126124
def patch(self, request, pk):
127-
# bootleg version of updating achievements via user
128-
if request.data.get("achievements") is not None:
129-
update_achievements(request.data.get("achievements"), pk)
125+
check_related_fields_update(request.data, pk)
126+
130127
return super().patch(request, pk)
131128

132129

0 commit comments

Comments
 (0)