Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create api files for IPR #38

Merged
merged 7 commits into from
Jan 31, 2024
Merged

Create api files for IPR #38

merged 7 commits into from
Jan 31, 2024

Conversation

Arti1946
Copy link
Collaborator

No description provided.

@Reagent992 Reagent992 changed the base branch from main to dev January 29, 2024 20:20
Copy link
Owner

@Reagent992 Reagent992 left a comment

Choose a reason for hiding this comment

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

Хорошая работа 💪
Оставил несколько комментариев и вопросов.

Скажи мне что у тебя по времени, фронтенд уже пробует подключатся к беку, этот PR желательно не затягивать.


class IPRSerializer(serializers.ModelSerializer):
creator = serializers.SlugRelatedField(
slug_field="username",
Copy link
Owner

Choose a reason for hiding this comment

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

Почему тут username возвращается, а не id?

slug_field="username",
read_only=True,
)
executor = serializers.RelatedField(read_only=True)
Copy link
Owner

Choose a reason for hiding this comment

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

Это что делает? Почему не id просто?

return True
if user.is_authenticated:
team_id = get_object_or_404(Team, boss_id=request.user.id)
if MiddleUsersTeams.objects.filter(
Copy link
Owner

Choose a reason for hiding this comment

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

3 дня назад упростил модель user, там уже нету модели MiddleUsersTeams

executor = get_object_or_404(User, id=executor_id)
if (
user.is_authenticated
and user.get_team() == executor.get_team()
Copy link
Owner

Choose a reason for hiding this comment

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

Тоже самое, User изменился, там теперь просто поле team

methods=["get"],
permission_classes=[permissions.IsAuthenticated],
)
def status(self, request, ipr_id):
Copy link
Owner

Choose a reason for hiding this comment

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

Сюда бы докстринг

ipr = get_object_or_404(IPR, id=ipr_id)
executor_id = self.kwargs.get("user_id")
executor = get_object_or_404(User, id=executor_id)
tasks_without_trail = ipr.tasks.exclude(status="trail").count()
Copy link
Owner

Choose a reason for hiding this comment

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

Тут можно не хардкодить trail и complete, а взять из статусов.

ipr/models.py Outdated
creator = models.ForeignKey(
User,
on_delete=models.CASCADE,
verbose_name="Создатель ИПР",
related_name="created_ipr",
)
creation_date = models.DateField("Дата создания ИПР", auto_now_add=True)
start_date = models.DateField("Дата начала работ по ИПР")
start_date = models.DateField(
Copy link
Owner

Choose a reason for hiding this comment

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

Почему тут появились blank=True, null=True ?

ipr/models.py Outdated
end_date = models.DateField("Дедлайн ИПР")
status = models.CharField("Статус ИПР", max_length=20, choices=STATUSES)
status = models.CharField(
"Статус ИПР", max_length=20, choices=STATUSES, default=STATUSES[0]
Copy link
Owner

Choose a reason for hiding this comment

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

@Reagent992
Copy link
Owner

Еще, т.к. проект уже на сервере:

  1. PR делаем в dev
  2. Есть изменения в моделях -> нужен новый файл миграции. ( внимательно, от файла миграции который сейчас есть в dev )

Copy link
Owner

@Reagent992 Reagent992 left a comment

Choose a reason for hiding this comment

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

Хорошо.👍
Оставил вопросы и комментарии.

class ExecutorSerializer(CustomUserSerializer):
class Meta:
fields = (
"first_name",
Copy link
Owner

Choose a reason for hiding this comment

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

надо добавить поле id

def get_status(self, obj):
if obj.status == Status.IN_PROGRESS and obj.start_date > obj.end_date:
obj.status = Status.TRAIL
return obj.status
Copy link
Owner

Choose a reason for hiding this comment

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

Это лучше сделать через сигналы, @greenpandorik взялся это делать.

Copy link
Owner

Choose a reason for hiding this comment

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

Таким образом, без obj.save() наверно даже значение в БД не сохранится.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

мне тогда пока оставить как есть? как появятся сигналы поменяю

Copy link
Owner

Choose a reason for hiding this comment

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

ок

Copy link
Collaborator

Choose a reason for hiding this comment

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

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

@@ -20,13 +14,10 @@ class IPR(models.Model):
verbose_name="Создатель ИПР",
related_name="created_ipr",
)
creation_date = models.DateField("Дата создания ИПР", auto_now_add=True)
Copy link
Owner

Choose a reason for hiding this comment

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

Дату создания не надо удалять в модели.
ПМ в чате имел ввиду "удалить из дизайна", он не знает чего у тебя там в модели происходит.
Для БД это полезная информация, с ней много чего можно сделать.

@@ -24,36 +27,39 @@ class Meta:
def get_queryset(self):
return IPR.objects.select_related("executor", "creator")
Copy link
Owner

Choose a reason for hiding this comment

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

При запросе на api/v1/iprs/ мы выдаем все ИПР пользователя делающего запрос.
При запросе с параметром /api/v1/iprs/?user_id={id} мы выдаем ИПР указанного пользователя.
Проверь эту логику.

@@ -24,36 +27,39 @@ class Meta:
def get_queryset(self):
Copy link
Owner

Choose a reason for hiding this comment

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

Ты удалил creation_date в модели, но оставил тут сортировку.
Надо вернуть поле в модель и сортировку тоже.
Тут она просто дублирует это значение из модели, можно удалить.

    class Meta:
        ordering = ["-creation_date"]

Copy link
Owner

Choose a reason for hiding this comment

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

Так же во viewset можно ограничить количество доступных HTTP-методов.
Нам хватит `http_method_names = ["get", "post", "patch", "head", "options"]


class IPRSerializerPost(serializers.ModelSerializer):
creator = serializers.PrimaryKeyRelatedField(read_only=True)
executor = serializers.PrimaryKeyRelatedField(read_only=True)
Copy link
Owner

Choose a reason for hiding this comment

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

Ты проверил создание ИПР ручками?
На первый взгляд это поля и def perform_create конфликтуют, но тут я могу ошибаться.

class IPRSerializer(serializers.ModelSerializer):
tasks = TaskSerializer(many=True, read_only=True)
creator = serializers.PrimaryKeyRelatedField(read_only=True)
executor = ExecutorSerializer(read_only=True)
status = serializers.SerializerMethodField()
Copy link
Owner

Choose a reason for hiding this comment

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

Не понимаю, зачем тут переопределять status и creator?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Creato - переопределил, что бы при создании ИПР он не запрашивался, а автоматически проставлялся в методе performe_create во view.

Status - что бы у статуса было актуальное значение. Но с учетом того что мы делаем это через сигналы, то я могу либо оставить пока как есть либо удалить и ждать пока будут готовы сигналы

Copy link
Owner

Choose a reason for hiding this comment

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

В смысле, у тебя же для создания ИПР другой сериализатор.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Да, а этот для отображения при GET запросе, при создании статус ставится автоматически в работе

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Все понял, затупил

Copy link
Owner

@Reagent992 Reagent992 left a comment

Choose a reason for hiding this comment

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

Отлично⭐

Если у тебя нету аргументов в пользу глобального фильтра, то его стоит убрать.
Остальное по желанию.

@@ -149,6 +150,9 @@
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
'DEFAULT_FILTER_BACKENDS': [
Copy link
Owner

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

согласен

serializer.save(creator=self.request.user, executor=executor)

def get_permissions(self):
if self.request.method in permissions.SAFE_METHODS:
Copy link
Owner

Choose a reason for hiding this comment

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

У нас весь проект на IsAuthenticated, можно сократить до:

        if self.request.method not in permissions.SAFE_METHODS:
            self.permission_classes = [TeamBossPermission]
        return super(IPRViewSet, self).get_permissions()

@action(
detail=True,
methods=["get"],
permission_classes=[permissions.IsAuthenticated],
Copy link
Owner

Choose a reason for hiding this comment

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

Тут тоже можно не указывать permission_classes=[permissions.IsAuthenticated],

return IPR.objects.filter(executor=self.request.user)

def get_serializer_class(self):
if self.request.method == "POST" or self.request.method == "PATCH":
Copy link
Owner

Choose a reason for hiding this comment

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

Можно короче:

if self.request.method in ("POST", "PATH"):

@@ -0,0 +1,8 @@
from django.db import models

Copy link
Owner

Choose a reason for hiding this comment

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

Название файла с ложным смыслом, это не единственное его использование.
Предлагаю просто оставить статусы

)
ordering = ("-creation_date",)
ordering = ("-id",)

Copy link
Owner

Choose a reason for hiding this comment

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

В админку тоже можно вернуть creation_date

@Reagent992 Reagent992 merged commit c071e96 into dev Jan 31, 2024
1 check passed
@Reagent992 Reagent992 deleted the Feature-IPR-api branch January 31, 2024 12:57
Reagent992 added a commit that referenced this pull request Feb 1, 2024
* API for IPR (#38)

* Create api files for IPR

* Небольшой ренейминг

* Fix for ipr serializers, views, model and fixture

* Fix IPR model and some other improvements

* fix serializer

* fix filtering

---------

Co-authored-by: Miron Sadykov <[email protected]>

* Улучшение уведомлений, тесты уведомлений. (#41)

1. Изменены ситуации создания уведомлений:
    - Изменения в задаче не создают уведомления.
    - Изменения даты ИПР создает уведомление.
    - Руководитель получает уведомление о закрытом ИПР.
2. Добавлена библиотека [django-dirtyfields](https://django-dirtyfields.readthedocs.io/en/stable/quickstart.html) | Для доступа к измененной информации в джанго сигнале `post_save` .
3. В связи с пунктом 2, в модели(Задачи и ИПР) добавлены миксины.
4. Тесты для автоматического создания уведомлений.
5. Тесты для API уведомлений.
6. Баш-скрипт для загрузки фикстур.

* Добавление функций в админку Задач (#42)

* Feature/tests ci (#43)

* В CI добавлен запуск тестов

* fix/ipr-api (#45)

* Fix view, permission, and add def_to_representation() to IPRSerializerPost

* Добавлено поле ruled_team в ответ users (#48)

* Добавил руссифицированную документацию для ИПР (#47)

---------

Co-authored-by: Артур Галиаскаров <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants