1

Follwing моя модельНесколько типов операций обновления для модели в Джанго рамках отдыха

class Group(Log_Active_Owned_Model_Mixin): 

    group_name = SafeCharField(max_length = 100, null=False, blank=False, sanitize_cb=safe_name_sanitizer) 
    group_creator = ForeignKey(to=PSS_User, null=False, related_name="group_creator") 
    members = ManyToManyField(to=PSS_User, through="GroupMemberShip", related_name="group_member") 

    class Meta: 
     ordering = ("Meta",) 

    ## other methods also exists in this class. 

class GroupMemberShip(Log_Active_Owned_Model_Mixin, ResolvableModelMixin): 

    MEMBER_NONE  = 1 
    MEMBER_ADMIN = 2 
    MEMBER_STANDARD = 4 


    VALID_MEMBERSHIPS = (
     (MEMBER_ADMIN,  "Admin" ), 
     (MEMBER_STANDARD, "Standard" ), 
     (MEMBER_NONE,  "None"  ) 
    ) 

    member = ForeignKey(to=PSS_User, null=False, related_name="groups") 
    group = ForeignKey(to=Group, null=False, related_name="members") 
    membership_type  = SmallIntegerField(editable=False, null=False, blank=False, choices=VALID_MEMBERSHIPS) 
    membership_request = ForeignKey(to=GroupMemberShipRequest, null=True, blank=True) # null True for group creator 

    class Meta: 
     ordering = ("date_created") 
     unique_together = ("member", "group") 

    ## other methods also exists in this class. 

class GroupMemberShipRequest(Log_Active_Owned_Model_Mixin): 

    GRP_MEMBERSHIP_REQ_STATUS_ACCEPTED = 1 
    GRP_MEMBERSHIP_REQ_STATUS_REJECTED = 2 
    GRP_MEMBERSHIP_REQ_STATUS_PENDING = 4 

    VALID_REQUEST_STATUSES = (
     (GRP_MEMBERSHIP_REQ_STATUS_ACCEPTED, "Accepted"), 
     (GRP_MEMBERSHIP_REQ_STATUS_REJECTED, "Rejected"), 
     (GRP_MEMBERSHIP_REQ_STATUS_PENDING,  "Pending") 
    ) 

    # TODO :- 
    # Add a field in request-type. There are two types of requests :- 
    # User can request admin to include him in the request. 
    # Admin can request other user, to become part of given group. 

    GRP_REQUEST_ACTIVE = 1 
    GRP_REQUEST_PASSIVE = 2 

    VALID_GRP_REQUESTS = (
     (GRP_REQUEST_ACTIVE, "Active"), 
     (GRP_REQUEST_PASSIVE, "Passive") 
    ) 

    request_initiator = ForeignKey(to=PSS_User, null=False, blank=False) 
    request_acceptor_rejector = ForeignKey(to=PSS_User, null=True, blank=False) 
    request_status = SmallIntegerField(null=False, editable=False, choices=VALID_REQUEST_STATUSES, default=GRP_MEMBERSHIP_REQ_STATUS_PENDING) 
    target_group = ForeignKey(to=Group, null=False, blank=False, related_name="members") 
    request_type = SmallIntegerField(null=False, editable=False, default=GRP_REQUEST_ACTIVE, choices=VALID_GRP_REQUESTS) 

Теперь Ниже перечислены различные типы операций, которые могут быть возможно с этой моделью Группа: -

  • создание группы
  • обновление Группа
    1. данные о группе обновлений.
    2. добавить/удалить член группы
    3. отправить приглашение на аутсайдер
    4. макияжа администратор/удалить администратор.
      • удаления группы

Для создания/удаления операции, все ясно, но я запутался об операции обновления, так как есть несколько вещей, которые могут быть обновлены. В настоящее время я добавил вспомогательные методы в классе Group, который выполняет все вышеупомянутые действия.

Мой вопрос: как я могу интегрировать его с DRF (Django Rest Framework) ModelViewSets. Поскольку существует только один метод update(), который может служить только одним из вышеупомянутых сценариев обновления. Как я могу обрабатывать другие сценарии обновлений? (Одно возможное решение, я думаю, использует запрос типа операции в запросе и проверяет его в методе update(), чтобы решить, какой метод модели вызывать, Но это наивное решение для бит. способ сделать это в Django Rest Framework?)

Заранее спасибо.

ответ

1

Рассмотрим эту статью Best Practices for Designing a Pragmatic RESTful API

рассматривать его как суб-ресурс с RESTful принципами. Например, API-интерфейс GitHub позволяет отображать gist с помощью PUT/gists /: id/star и notar с помощью DELETE/gists /: id/star.

В вашем случае существует 4 различных действия с группой. Я вижу два способа решения проблемы в DRF. Следуя верхушку выше, вы можете использовать @detail_route декоратора:

from rest_framework.decorators import detail_route 

class GroupViewSet(viewsets.ModelViewset): 

    @detail_route(methods=['put', 'delete']) 
    def send_invite(self, request, pk=None): 
     # check for the method provided 
     # do your logic and return a Response object 
     pass 

Это добавит дополнительную конечную точку viewsets маршрутизатора, которые следуют после детальной страницы

/api/groups/:id/send_invite/ 

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

/api/groups/:id/admin/:id/ 

Но иногда это является излишеством, и это нарушает наилучшую практику для проектирования API