You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

Обращайся к этому гайду, если не знаешь, куда писать ту или иную часть функциональности бэкенда.

Важно: многие куски кода не соответствуют этим правилам. Это не значит, что можно забивать на эти правила. И это не значит, что надо ломиться переписывать абсолютно всё на эти правила.

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

Итак, ты пишешь...

  1. Логику модели (например, вычисление данных, которые будут сохраняться в модели)
    1. Твоя цель - метод в классе модели. Если нужно дополнительно сохранять полученные данные - переопредели метод save
    2. Если ты хочешь перехватывать события сохранения/удаления объекта и нагружать их доп.логикой - тебе понадобятся сигналы pre_save/post_save/pre_delete/etc.
      1. Важно: при множественном добавлении/удалении объектов с помощью bulk_create или с помощью админки, сигналы не обрабатываются. Учитывай это при работе с сигналами. 

  2. Валидацию данных (например, проверку на то, что создаваемая бронь стиралки не пересекается ни с какими другими бронями): уноси её в сериализатор
    1. Обрати внимание: чтобы отличить в сериализаторе процесс создания модели от процесса изменения - посмотри значение атрибута "pk". При создании primary key будет None, т.к. объект ещё не попал в базу данных
    2. Для проверки одного конкретного значения в отрыве от остальных - используй метод validate_<field_name>
    3. Для проверки объекта в целом (как в примере из п.2) - используй метод validate

  3. Проверку прав доступа
    1. Пиши нужные методы has_perm_<какое-нибудь действие> в файле permissions.py.
      1. Методы has_perm_<какое-нибудь действие> нужны только для сериализаторов, не используй их во вьюхах
    2. Пиши классы прав в файле permissions.py.
      1. Классы прав доступа нужны только для вьюх. Хорошая практика - писать методы has_perm_<какое-нибудь действие> и потом их же использовать во вьюхах
    3. Не делай проверки на права доступа в методах get()/post()/etc. вьюхи или в сериализаторах - это не их зона ответственности. Методы get()/post() в 95% случаев должны только звать родительский соотв. метод
    4. Не используй user.has_perm("permission name") нигде, кроме файла permissions.py
      1. (это нужно на те случаи, когда логика проверки прав доступа сложнее, чем просто вызов user.has_perm.
        Такое случается довольно часто, и копипаст логики проверки прав в этих случаях - это выстрел себе в ногу)
    5. Если нужно динамически в зависимости от запроса определять уровень прав (например: в запросе на удаление бронирования любой пользователь может удалить свою бронь, а чужую - только админ)- используй метод get_permissions.
    6. Если тебе нужен контекст для использования в классе прав (например, при запросах к стиралке тебе всегда нужно знать, о какой компоненте стиралки речь) - можешь переопределить метод setup() вьюхи, в котором добавить атрибуты
      1. Не забывай вызвать super().setup(request, *args, **kwargs)
      2. Если берёшь параметры из kwargs (GET-параметров) или request.data (POST-параметры) - не забывай проверять их наличие в запросе и кидать эксепшн rest_framework.exceptions.ParseError
  4. Пример хорошего кода проверки прав доступа:
  5. Эндпоинт (вьюху)
    1. Фильтрацию объекта (например, тебе прилетел запрос отобразить список бронирований с момента X по момент Y):
      1. Переопредели метод get_queryset или get_object 
    2. Сохранение/удаление объекта:
      1. В случае, когда тебе надо одновременно сохранить/изменить/удалить несколько объектов в одной вьюхе - используй хуки вьюхи (методы perform_create/perform_update/perform_destroy)
        1. Не забывай использовать @transaction.atomic, если тебе нужна консистентность при изменении нескольких объектов (например - создание  


  • No labels