django rest框架中模型的多种更新操作
Multiple types of update operations for a model in django rest framework
下面是我的模型
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)
下面是不同类型的操作,可以使用此组模型实现:-
- 创建群组
- 更新群组
- 更新组详细信息。
- add/remove 群成员
- 向外人发送邀请
- 成为 admin/remove 管理员。
- 删除群组
对于create/delete操作,事情很清楚,但我对更新操作感到困惑,因为有很多东西可以更新。目前,我已经在 Group class 中添加了辅助方法,它完成了上述所有活动。
我的问题是,如何将它与 DRF(Django Rest Framework)ModelViewSets 集成。由于只有一个 update() 方法,只能服务于上述更新场景之一。我如何处理其他更新场景?(一个可能的解决方案,我认为是在请求中使用操作类型标志并在 update() 方法中检查它来决定调用哪个模型方法,但它有点天真解决方案。有没有更好的在 Django Rest Framework 中如何做到这一点?)
提前致谢。
考虑这篇文章 Best Practices for Designing a Pragmatic RESTful API
Treat it like a sub-resource with RESTful principles. For example, GitHub's API lets you star a gist with PUT /gists/:id/star and unstar with 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
它将在详细信息页面之后向视图集路由器添加额外的端点
/api/groups/:id/send_invite/
它可以很好地处理简单的任务。但是当你需要一个复杂的嵌套逻辑时,你可能会发现这个包 drf-nested-routers 很有用。它允许您在彼此之上构建 viesets。
/api/groups/:id/admin/:id/
但有时它有点矫枉过正,违反了设计的最佳实践API
下面是我的模型
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)
下面是不同类型的操作,可以使用此组模型实现:-
- 创建群组
- 更新群组
- 更新组详细信息。
- add/remove 群成员
- 向外人发送邀请
- 成为 admin/remove 管理员。
- 删除群组
对于create/delete操作,事情很清楚,但我对更新操作感到困惑,因为有很多东西可以更新。目前,我已经在 Group class 中添加了辅助方法,它完成了上述所有活动。
我的问题是,如何将它与 DRF(Django Rest Framework)ModelViewSets 集成。由于只有一个 update() 方法,只能服务于上述更新场景之一。我如何处理其他更新场景?(一个可能的解决方案,我认为是在请求中使用操作类型标志并在 update() 方法中检查它来决定调用哪个模型方法,但它有点天真解决方案。有没有更好的在 Django Rest Framework 中如何做到这一点?)
提前致谢。
考虑这篇文章 Best Practices for Designing a Pragmatic RESTful API
Treat it like a sub-resource with RESTful principles. For example, GitHub's API lets you star a gist with PUT /gists/:id/star and unstar with 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
它将在详细信息页面之后向视图集路由器添加额外的端点
/api/groups/:id/send_invite/
它可以很好地处理简单的任务。但是当你需要一个复杂的嵌套逻辑时,你可能会发现这个包 drf-nested-routers 很有用。它允许您在彼此之上构建 viesets。
/api/groups/:id/admin/:id/
但有时它有点矫枉过正,违反了设计的最佳实践API