【问题标题】:De-serializing many to many field with a through table in DRF使用 DRF 中的直通表反序列化多对多字段
【发布时间】:2020-07-09 10:54:45
【问题描述】:

我正在使用 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)

对于用户,我目前正在使用 Django 的默认身份验证用户模型,并通过 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的新手,所以从上面可能有很多需要改进的地方。我真的很感激每一个帮助!

【问题讨论】:

    标签: python django django-rest-framework serialization


    【解决方案1】:

    您可以覆盖序列化程序中的更新方法,并从 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__"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2021-03-19
      • 2019-03-16
      相关资源
      最近更新 更多