Django Rest Framework: обновление подобъекта новым маршрутом, а не частичное обновление модели - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь создать объект API Roster, в котором в качестве подобъекта есть список членов. Однако я не хочу обновлять подобъект путем частичного обновления объекта реестра - вместо этого я хочу маршрут для «добавления члена» и «удаления члена».

Цель:

GET /Roster/{ROSTERID}

тело ответа:

{
    id: {roster id},
    members: # members sub object is read only
      [
        {member subobject},
        {member subobject},
         ...
      ],
}

POST /Roster/{RosterID}/AddMember

{
    {member id},
    {member id}, ...
}

, а затем аналогичная вещь для удаления члена.

Примечание. Я хочу иметь возможность передавать существующий идентификатор участника. Я не хочу создавать новых членов здесь.

Что я должен искать в документах, чтобы иметь возможностьдобавить маршрут для обновления списка участников с идентификатором пользователя, вместо того, чтобы передавать весь пользовательский объект?

serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']

class RosterSerializer(serializers.ModelSerializer):
    members = serializers.ListField(
        child=UserSerializer()
    )

    class Meta:
        model = Roster
        fields = ('id', 'name', 'members')
        depth = 2

app/models.py

class Members(User):
    on_pto = models.BooleanField(default=False)

class Roster(models.Model):
    objects = models.Manager()

    name = models.CharField(max_length=80, blank=True, default='', unique=True, null='')
    members = models.ForeignKey(
        Members,
        limit_choices_to={'on_pto': False},
        blank=True,
        null=True,
        related_name='members',
        on_delete=models.CASCADE
    )

views.py

class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all().order_by('-id')
    serializer_class = GroupSerializer


class RosterViewSet(viewsets.ModelViewSet):
    """"""

    queryset = Roster.objects.all().order_by('-id')
    serializer_class = RosterSerializer

1 Ответ

1 голос
/ 07 октября 2019

Вам, вероятно, нужно изменить свои модели, чтобы разрешить использование нескольких членов в реестре , либо выполнить множество-ко-многим для списка, либо установить отношение FK для пользователя. Таким образом, вы можете добавить несколько членов в реестр.

Для этого вы можете использовать собственный маршрут, подобный этому. Показано ниже для add_member и затем аналогично для remove_member, измените, чтобы удалить из members_set для объекта списка.

class RosterViewSet(viewsets.ModelViewSet):

    queryset = Roster.objects.all().order_by('-id')
    serializer_class = RosterSerializer

    @action(detail=True, methods=['post'])
    def add_member(self, request, pk=None):
        errors = []
        response = {}
        roster = self.get_object()
        members_dict = request.data['members']
        if not isinstance(members_dict, list):
            errors.append("Invalid request format")
        else:
            for id in members_dict:
                try:
                    member = User.objects.get(pk=id)
                    roster.members.add(member)
                    roster.save()
                    status_code = status.HTTP_200_OK
                except Member.DoesNotExist:
                    errors.append("Member id {} not found".format(id))
         if errors:
            response['errors'] = errors
            status_code = status.HTTP_400_BAD_REQUEST

    return response.Response(response, status=status_code)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...