Обновлять данные в сериализаторе при создании объекта с помощью django rest framework - PullRequest
0 голосов
/ 25 января 2019

Мой models.py выглядит следующим образом:

class Activity(models.Model):
    name = models.CharField(max_length=50, unique=True)
    description = model.TextField(max_length=500)

class Jira(models.Model):
    jira_id = models.CharField(max_length=50, unique=True)
    activity = model.ForeignKey(Activity, null=True on_delete=models.SET_NULL)

С одним действием может быть связано несколько билетов Jira. Поэтому я использую внешний ключ для обозначения отношения один ко многим.

Мой сериализатор для создания нового действия выглядит следующим образом:

class ActivityCreateSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=50)
    description = serializers.CharField(max_length=50)
    jira_ticket = serializers.ReadOnlyField()

Мой взгляд выглядит следующим образом:

class ActivtyViewSet(viewsets.ViewSet):
    def create(self, request):
        serializer = ActiityCreateSerializer(data=request.data)
        if serializer.is_valid():
           #jira_ticket = make call to jira and get a valid ticket number
           serializer.save()
           return Response(serializer.data, status=status.HTTP_201_CREATED)

Как видно, при создании нового действия внешний API-интерфейсcall должен выйти в систему продажи билетов Jira, чтобы создать новый jira_ticket.Это происходит успешно, и я получаю номер jira_ticket.У меня вопрос в два раза:

  1. Как сохранить билет Jira в БД, поскольку он не является частью сериализатора и получается только после того, как запрос сделан из внешнего вызова API?
  2. Как добавить номер билета jira в выходной файл сериализатора, поскольку serializer.data является неизменным, и я не могу добавить jira_ticket к ответу dict?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вы можете переопределить пресавный хук perform_create() из drf, что-то вроде этого.

class ActivtyViewSet(viewsets.ViewSet):
    def perform_create(self, serializer):
        serializer(jira_number=get_jira_ticket_number(serializer.data))
        serializer.save()

Ссылка: https://www.django -rest-framework.org / api-guide / generic-views/ (Поиск perform_create)

Но я полагаю, вызов стороннего API в вашем цикле запрос-ответ не является хорошей практикой.Что произойдет, если что-то пойдет не так, будет извлекать ticket_number из jira?

Я бы вернул все имеющиеся у нас данные и вызвал бы фоновую задачу, чтобы извлечь ticket_number из jira и обновить сохраненный объект таким же образом.Клиент должен продолжать опрос для jira ticket_number.Или что-то вроде этого.

0 голосов
/ 25 января 2019

В представлении после вызова serializer.save () вызовите API для билета jira и используйте его для хранения объекта билета jira с объектом действия, возвращенным из метода serializer.save (). Вам также необходимо обновить ответ, включив в него данные билета jira, поле только для чтения не требуется, так как представление обновит данные ответа. Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...