Skip to content
Merged
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
22 changes: 21 additions & 1 deletion project_rates/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,29 @@


class ProjectScoreCreateSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
self.criteria_to_get = kwargs.pop("criteria_to_get", None)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

для этого не было особых причин, но я подумал, что так передавать аргумент в классе сериалайзера будет удобно

super(ProjectScoreCreateSerializer, self).__init__(*args, **kwargs)

class Meta:
model = ProjectScore
fields = ["criteria", "user", "project", "value"]
fields = ("criteria", "user", "project", "value")
validators = []
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

потому что иначе у меня будет автоматическая проверка на unique_together, а это мне не нужно, потому что дальше по коду будет обновление/создание оценок. если тут вылезет ошибка, то create_in_bulk обновить их не сможет


def get_queryset(self):
Copy link
Member Author

@sh1nkey sh1nkey Feb 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сериалайзер подгружает данные, оказывается. скорее всего, для каждого объекта в списке отдельно. это не круто. я не доверяю ему, поэтому сделал по своему

return self.Meta.model.objects.filter(
criteria__id__in=self.criteria_to_get
).select_related("criteria", "project", "user")

def validate(self, data):
criteria = data["criteria"]
ProjectScoreValidate(
criteria_type=criteria.type,
value=data.get("value"),
criteria_min_value=criteria.min_value,
criteria_max_value=criteria.max_value,
)
return data


class CriteriaSerializer(serializers.ModelSerializer):
Expand Down
47 changes: 29 additions & 18 deletions project_rates/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
CriteriaSerializer,
ProjectScoreSerializer,
ProjectScoreGetSerializer,
serialize_data_func,
)
from users.permissions import IsExpert, IsExpertPost

Expand All @@ -24,28 +23,40 @@ class RateProject(generics.CreateAPIView):
serializer_class = ProjectScoreCreateSerializer
permission_classes = [IsExpertPost]

def create(self, request, *args, **kwargs):
# try:
def get_needed_data(self) -> tuple[dict, list[int]]:
data = self.request.data

user = self.request.user.id
user_id = self.request.user.id
project_id = self.kwargs.get("project_id")

criteria_to_get = []
criteria_to_get = [
criterion["criterion_id"] for criterion in data
] # needed for validation later
for criterion in data:
criterion["user_id"] = user
criterion["project_id"] = project_id
criteria_to_get.append(criterion["criterion_id"])

serialize_data_func(criteria_to_get, data)
ProjectScore.objects.bulk_create(
[ProjectScore(**score) for score in data],
update_conflicts=True,
update_fields=["value"],
unique_fields=["criteria", "user", "project"],
)
criterion["user"] = user_id
criterion["project"] = project_id
criterion["criteria"] = criterion.pop("criterion_id")

return data, criteria_to_get

def create(self, request, *args, **kwargs) -> Response:
try:
data, criteria_to_get = self.get_needed_data()

serializer = ProjectScoreCreateSerializer(
data=data, criteria_to_get=criteria_to_get, many=True
)
serializer.is_valid(raise_exception=True)

ProjectScore.objects.bulk_create(
[ProjectScore(**item) for item in serializer.validated_data],
update_conflicts=True,
update_fields=["value"],
unique_fields=["criteria", "user", "project"],
)

return Response({"success": True}, status=status.HTTP_201_CREATED)
return Response({"success": True}, status=status.HTTP_201_CREATED)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)


class RateProjects(generics.ListAPIView):
Expand Down