Skip to content

Commit

Permalink
Feature/tasks api (#23)
Browse files Browse the repository at this point in the history
* Add app ratings, create test for ratings and tasks

* Some refactoring

* Delete ipr/migrations directory

* Исправил комментарии с собрания v2

* Fix isort
  • Loading branch information
greenpandorik authored Jan 27, 2024
1 parent 486ae52 commit 997ccba
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 160 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,5 @@ Thumbs.db
.vscode
*/migrations/*
/static/
/ipr/migrations/
# Миграции убраны из git. Т.к. до существования БД проще без них.
17 changes: 17 additions & 0 deletions api/v1/serializers/ratings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from rest_framework import serializers

from ratings.models import Rating


class RatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
fields = [
"id",
"content_type",
"object_id",
"user",
"rating",
"created_at",
]
read_only_fields = ["user"]
10 changes: 9 additions & 1 deletion api/v1/serializers/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@ class TaskSerializer(serializers.ModelSerializer):
creator = SlugRelatedField(slug_field="username", read_only=True)

class Meta:
exclude = ("creation_date",)
fields = (
"name",
"description",
"creator",
"creation_date",
"start_date",
"end_date",
"status",
)
model = Task
11 changes: 11 additions & 0 deletions api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from rest_framework import routers

from api.v1.views.notifications_view import NotificationViewSet
from api.v1.views.ratings_view import IPRRatingCreateView, TaskRatingCreateView
from api.v1.views.task import TaskViewSet
from api.v1.views.users_view import UserViewSet

Expand All @@ -20,6 +21,16 @@
urlpatterns = [
path("", include(v1_router.urls)),
path("auth/", include("djoser.urls.jwt")),
path(
"tasks/<int:task_id>/ratings/",
TaskRatingCreateView.as_view(),
name="task-rating-create",
),
path(
"iprs/<int:ipr_id>/ratings/",
IPRRatingCreateView.as_view(),
name="ipr-rating-create",
),
]

# ---------------------------------------------------------------------SWAGGER
Expand Down
43 changes: 43 additions & 0 deletions api/v1/views/ratings_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from rest_framework import generics, status
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response

from api.v1.serializers.ratings import RatingSerializer
from ipr.models import IPR
from ratings.models import Rating
from tasks.models import Task


class RatingCreateListView(generics.CreateAPIView, generics.ListAPIView):
queryset = Rating.objects.all()
serializer_class = RatingSerializer
content_model = None

def get_content_object(self):
object_id = self.kwargs.get(f"{self.content_model}_id")
return get_object_or_404(self.content_model, id=object_id)

def get_queryset(self):
content_object = self.get_content_object()
return Rating.objects.filter(
content_type__model=self.content_model, object_id=content_object.id
)

def post(self, request, *args, **kwargs):
content_object = self.get_content_object()

serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save(
content_object=content_object, user=self.request.user
)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class TaskRatingCreateView(RatingCreateListView):
content_model = Task


class IPRRatingCreateView(RatingCreateListView):
content_model = IPR
10 changes: 10 additions & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"ipr.apps.IprConfig",
"tasks.apps.TasksConfig",
"users.apps.UsersConfig",
"ratings.apps.RatingsConfig",
"core.apps.CoreConfig",
]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Expand Down Expand Up @@ -167,9 +168,18 @@
EMAIL_LENGTH = 254
NAME_LENGTH = 150
MAX_LEN_COMMENT_TEXT = 200
DESCRIPTION_LEN = 500
SKILL_LEN = 255
RESTRICTED_USERNAMES = (
"me",
"admin",
"administrator",
"root",
)
RATING_CHOICES = (
(1, "1 звезда"),
(2, "2 звезды"),
(3, "3 звезды"),
(4, "4 звезды"),
(5, "5 звезд"),
)
147 changes: 0 additions & 147 deletions ipr/migrations/0001_initial.py

This file was deleted.

File renamed without changes.
17 changes: 17 additions & 0 deletions ratings/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.contrib import admin

from ratings.models import Rating


class RatingAdmin(admin.ModelAdmin):
list_display = (
"content_type",
"object_id",
"content_object",
"user",
"rating",
"created_at",
)


admin.site.register(Rating, RatingAdmin)
7 changes: 7 additions & 0 deletions ratings/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.apps import AppConfig


class RatingsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "ratings"
verbose_name = "Оценка"
28 changes: 28 additions & 0 deletions ratings/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models

User = get_user_model()


class Rating(models.Model):
content_type = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
limit_choices_to={"model__in": ["task", "ipr"]},
)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey("content_type", "object_id")

user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
rating = models.IntegerField(choices=settings.RATING_CHOICES)
created_at = models.DateTimeField(auto_now_add=True)

class Meta:
verbose_name = "Оценки"
verbose_name_plural = "Оценки"

def __str__(self):
return f"{self.content_object} - {self.rating} от {self.user}"
Loading

0 comments on commit 997ccba

Please sign in to comment.