删除多对多关系的成员 Django Rest Framework

Rog*_*mas 3 python django manytomanyfield django-rest-framework

给定以下系统

#  Models
class Team(models.Model):
    name = models.CharField(max_length=128)


class Player(models.Model):
    name = models.CharField(max_length=128)
    teams = models.ManyToManyField(Team)

#  Serializers
class PlayerSerializer(serializers.ModelSerializer):
    teams = serializers.PrimaryKeyRelatedField(many=True, queryset=League.objects.all(), required=False)

    class Meta:
        model = Team
        fields = ('id', 'name', 'teams')

# Views
class TeamViewSet(viewsets.ModelViewSet):
    queryset = Team.objects.all()
    serializer_class = TeamSerializer
Run Code Online (Sandbox Code Playgroud)

基本上一个球员可以在很多球队

所以问题是,如何实现端点来管理玩家与团队的关系。假设我们有两支 id 为 1 和 2 的球队,我创建了一个球员

POST /players/ {'name': 'player1'} 该玩家的 ID 为 1

我想将玩家添加到团队 1 和 2,然后从团队 2 中删除玩家

通过此设置,我可以执行 PATCH /players/1/ {'teams': [1, 2]}

我现在如何从团队 2 中删除玩家 1?

另外,使用补丁请求将玩家 1 添加到团队 1 和团队 2 是执行此操作的正确方法吗?

tre*_*zko 5

解决这个问题我最喜欢的方法是在为此目的的视图集上创建一个详细路线端点。下面是一个示例:

# Views
class TeamViewSet(viewsets.ModelViewSet):
    queryset = Team.objects.all()
    serializer_class = TeamSerializer

    @action(methods=['delete'], detail=True)
    def remove_players_from_team(self, request):
        team = self.get_object()
        players_to_remove = request.data['players']
        # ...
Run Code Online (Sandbox Code Playgroud)

从那里,您可以添加逻辑以从团队中删除玩家。端点将类似于:<base_url>/api/teams/<team_id>/remove_players_from_team并期望参数players和请求类型DELETE,您可以期望多种方式。

这也可以应用于添加玩家,并且如果需要的话可以应用于反向关系。

至于允许使用哪种方法,请考虑正在做什么。如果要添加玩家,最好提出POST请求。如果要删除它们,最好选择DELETE. 如果您希望将它们视为更新,请使用PATCH.

如果您有兴趣使用它,请查看 DRF 文档