Десериализация поля многие ко многим с помощью сквозной таблицы в DRF - PullRequest
0 голосов
/ 09 июля 2020

Я работаю над созданием веб-сайта, подобного Trello, с помощью Django Rest Framework. Я хочу добавить выбранных пользователей в модель 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)

Для пользователя я в настоящее время используется модель Auth User по умолчанию Django и расширяется с помощью модели Profile через поле OneToOne.

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

I хотел бы знать, какое поле / отношения / другой сериализатор должен быть назначен на 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 голосов
/ 09 июля 2020

Вы можете переопределить метод обновления в своем сериализаторе и получить идентификаторы пользователей со стороны клиента из initial_data

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__"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...