在DRF中使用穿透表将多对多字段反序列化

时间:2020-07-09 10:54:45

标签: python django django-rest-framework serialization

我正在使用Django Rest Framework开发类似Trello的网站。 我想将选定的用户添加到BoardAccess模型中,这是User模型和Board模型的通过表,其中两个处于多对多关系。添加到BoardAccess表中意味着相应的用户将有权访问匹配的板。

Models.py

class Board(models.Model):
    name           = models.CharField(max_length=50)
    access_granted = models.ManyToManyField(User, through='BoardAccess', related_name='access_boards')
    team           = models.ForeignKey(Team, on_delete=models.CASCADE) # a team can have many boards


class BoardAccess(models.Model):
    user    = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    board   = models.ForeignKey('Board', on_delete=models.CASCADE)

对于User,我目前正在使用Django的默认Auth User模型,并通过OneToOne字段将其扩展为Profile模型。

Serializers.py

class BoardAccessSerializer(serializers.ModelSerializer):
    members = serializers.SerializerMethodField()
    added_users = # ???
    new_name = serializers.CharField(
        write_only=True, required=False, source='name') # in case of requests for renaming the board

    def get_members(self, instance):
        members = User.objects.filter(profile__team=instance.team)
        return UserBoardSerializer(members, many=True).data

我想知道应该为added_users分配哪个字段/关系/另一个序列化程序,我认为应该为write_only=True,以便成功地反序列化来自客户端的输入侧包含所选用户的主键。

get_members()方法用于首先显示所有团队成员的信息,客户将从中选择要添加到董事会的用户。

Views.py

class BoardAccessRetrieveUpdateAPIView(generics.RetrieveUpdateAPIView):
    serializer_class = BoardAccessSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        team_id = self.kwargs.get('team_id')
        team = get_object_or_404(Team, id=team_id)
        queryset = Board.objects.select_related(
            'team').prefetch_related(
            'access_granted').filter(team=team)
        return queryset

我是DRF的新手,因此,从以上几点可能有很多要改进的地方。我非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您可以在序列化程序中覆盖update方法,并从initial_data获取客户端的用户ID

def update(self, instance, validated_data):
    // do the actions on create
    users = self.initial_data.get('users')
    instance.access_granted.add(*users)
    instance.save()
    return instance

在使用ModelSerializer时,还必须添加Meta类:

 class BoardAccessSerializer(serializers.ModelSerializer):

     class Meta:
           model = Board
           fields = "__all__"
相关问题