Skip to content
Merged

Dev #47

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions projects/migrations/0008_alter_project_description_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Generated by Django 4.1.3 on 2022-11-18 11:45

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


def set_userachievement_user_to_not_null(apps, schema_editor):
Project = apps.get_model('projects', 'Project')
Project.objects.filter(leader=None).delete()


class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("industries", "0001_initial"),
("projects", "0007_remove_collaborator_unique_collaorator_and_more"),
]

operations = [
migrations.AlterField(
model_name="project",
name="description",
field=models.TextField(blank=True, null=True),
),
migrations.AlterField(
model_name="project",
name="image_address",
field=models.URLField(blank=True, null=True),
),
migrations.AlterField(
model_name="project",
name="industry",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="projects",
to="industries.industry",
),
),
migrations.RunPython(set_userachievement_user_to_not_null),
migrations.AlterField(
model_name="project",
name="leader",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="leaders_projects",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AlterField(
model_name="project",
name="presentation_address",
field=models.URLField(blank=True, null=True),
),
migrations.AlterField(
model_name="project",
name="region",
field=models.CharField(blank=True, max_length=256, null=True),
),
migrations.AlterField(
model_name="project",
name="short_description",
field=models.TextField(blank=True, null=True),
),
]
19 changes: 8 additions & 11 deletions projects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,24 @@ class Project(models.Model):
"""

name = models.CharField(max_length=256, null=True, blank=True)
description = models.TextField(blank=True)
short_description = models.TextField(blank=True)
region = models.CharField(max_length=256, blank=True)
description = models.TextField(null=True, blank=True)
short_description = models.TextField(null=True, blank=True)
region = models.CharField(max_length=256, null=True, blank=True)
step = models.PositiveSmallIntegerField(choices=VERBOSE_STEPS, null=True, blank=True)

industry = models.ForeignKey(
Industry,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="projects",
)
presentation_address = models.URLField(blank=True)
image_address = models.URLField(blank=True)
presentation_address = models.URLField(null=True, blank=True)
image_address = models.URLField(null=True, blank=True)

leader = models.ForeignKey(
User,
on_delete=models.SET_NULL,
null=True,
on_delete=models.CASCADE,
related_name="leaders_projects", # projects in which this user is the leader
)

Expand Down Expand Up @@ -85,10 +85,7 @@ class Achievement(models.Model):
status = models.CharField(max_length=256, null=False)

project = models.ForeignKey(
Project,
on_delete=models.SET_NULL,
null=True,
related_name="achievements",
Project, on_delete=models.SET_NULL, null=True, related_name="achievements"
)

objects = AchievementManager()
Expand Down
18 changes: 2 additions & 16 deletions projects/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from industries.models import Industry
from projects.models import Project, Achievement, Collaborator
from projects.validators import validate_project
from users.models import CustomUser
from vacancy.serializers import ProjectVacancyListSerializer


Expand Down Expand Up @@ -95,10 +94,6 @@ class Meta:


class ProjectListSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
# might be unnecessary
self.max_collaborator_count = kwargs.pop("max_collaborator_count", 4)
super().__init__(*args, **kwargs)

collaborators = serializers.SerializerMethodField(method_name="get_collaborators")
collaborator_count = serializers.SerializerMethodField(
Expand All @@ -111,8 +106,9 @@ def get_collaborator_count(cls, obj):
return len(obj.collaborator_set.all())

def get_collaborators(self, obj):
max_collaborator_count = 4
return CollaboratorSerializer(
instance=obj.collaborator_set.all()[: self.max_collaborator_count], many=True
instance=obj.collaborator_set.all()[:max_collaborator_count], many=True
).data

class Meta:
Expand Down Expand Up @@ -144,16 +140,6 @@ def validate(self, data):
super().validate(data)
return validate_project(data)

def create(self, validated_data):
industry = Industry.objects.get(id=validated_data.pop("industry"))
leader = CustomUser.objects.get(id=validated_data.pop("leader"))
project = Project.objects.create(
**validated_data,
industry=industry,
leader=leader,
)
return project


class ProjectIndustrySerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
Expand Down
3 changes: 1 addition & 2 deletions projects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# Doesn't work if not explicitly set like this
serializer.validated_data["leader"] = request.user.id
serializer.validated_data["industry"] = request.data["industry"]
serializer.validated_data["leader"] = request.user

self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
Expand Down
30 changes: 30 additions & 0 deletions users/migrations/0019_alter_userachievement_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.1.3 on 2022-11-18 11:18

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


def set_userachievement_user_to_not_null(apps, schema_editor):
UserAchievement = apps.get_model('users', 'UserAchievement')
UserAchievement.objects.filter(user=None).delete()


class Migration(migrations.Migration):

dependencies = [
("users", "0018_alter_customuser_about_me"),
]

operations = [
migrations.RunPython(set_userachievement_user_to_not_null),
migrations.AlterField(
model_name="userachievement",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="achievements",
to=settings.AUTH_USER_MODEL,
),
),
]
16 changes: 11 additions & 5 deletions users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,14 @@ class CustomUser(AbstractUser):

objects = CustomUserManager()

def get_member_key_skills(self) -> str:
def get_member_key_skills(self) -> list[str]:
if self.user_type == CustomUser.MEMBER:
return str(self.member.key_skills)
return ""
return [
skill.strip()
for skill in self.member.key_skills.split(",")
if skill.strip()
]
return []

def __str__(self):
return f"User<{self.id}> - {self.first_name} {self.last_name}"
Expand All @@ -106,8 +110,7 @@ class UserAchievement(models.Model):

user = models.ForeignKey(
CustomUser,
on_delete=models.SET_NULL,
null=True,
on_delete=models.CASCADE,
related_name="achievements",
)

Expand Down Expand Up @@ -170,6 +173,9 @@ class Member(models.Model):
Industry, blank=True, related_name="members"
)

def get_key_skills(self) -> list[str]:
return [skill.strip() for skill in self.key_skills.split(",") if skill.strip()]

def __str__(self):
return f"Member<{self.id}> - {self.user.first_name} {self.user.last_name}"

Expand Down
7 changes: 0 additions & 7 deletions users/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ class IsAchievementOwnerOrReadOnly(BasePermission):
Allows access to update only to himself.
"""

def has_permission(self, request, view) -> bool:
if request.method in SAFE_METHODS or (
request.user and request.user.id == request.data.get("user")
):
return True
return False

def has_object_permission(self, request, view, obj):
if request.method in SAFE_METHODS or (obj.user == request.user):
return True
Expand Down
17 changes: 12 additions & 5 deletions users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@
class AchievementListSerializer(serializers.ModelSerializer):
class Meta:
model = UserAchievement
fields = [
"id",
"title",
"status",
]
fields = ["id", "title", "status"]
# extra_kwargs = {"user": {"write_only": True}}
ref_name = "Users"


class KeySkillsField(serializers.Field):
def to_representation(self, value):
return [skill.strip() for skill in value.split(",") if skill.strip()]

def to_internal_value(self, data):
return ",".join(data)


class MemberSerializer(serializers.ModelSerializer):
key_skills = KeySkillsField()

class Meta:
model = Member
fields = [
Expand Down
20 changes: 20 additions & 0 deletions users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,26 @@ class AchievementList(ListCreateAPIView):
serializer_class = AchievementListSerializer
permission_classes = [IsAchievementOwnerOrReadOnly]

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.validated_data["user"] = request.user
# warning for someone who tries to set user variable (the user will always be yourself anyway)
if (
request.data.get("user") is not None
and request.data.get("user") != request.user.id
):
return Response(
{
"error": "you can't edit USER field for this view since "
"you can't create achievements for other people"
},
status=status.HTTP_403_FORBIDDEN,
)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)


class AchievementDetail(RetrieveUpdateDestroyAPIView):
queryset = UserAchievement.objects.get_achievements_for_detail_view()
Expand Down