Есть ли способ получить определенные "поля" из request.data, отправленных в API фреймворка Django REST методом POST?

У меня есть модель Project, с полем project_code. Когда API получает POST-запрос, request.data также будет содержать код проекта. Затем я хочу отфильтровать объекты модели Project на основе кода проекта в request.data

После того как я связал request.data project_code с полем project_code модели Project, я хочу сохранить объект модели Ticket в базе данных. Внутри моей модели Ticket есть поле под названием project, которое связано с моделью Project с помощью ForeignKey.

По сути, код_проекта внутри POST request.data должен быть использован для того, чтобы сохранить мою модель Ticket в базе данных с правильным внешним ключом модели Project.

Вот мои модели:

from django.db import models

class Project(models.Model):
    
    project_code = models.TextField(blank=True)
    project_description = models.TextField(blank=True)

    def __str__(self):
        return self.project_code

class Ticket(models.Model):

    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    ticket_url = models.TextField(blank=True)
    time_submitted = models.DateField(blank=True, auto_now_add=True)
    description = models.TextField(blank=True)
    user = models.TextField(blank=True)
    type = models.TextField(blank=True)

    def __str__(self):
        return self.description

Вот мои сериализаторы:

from rest_framework import serializers
from ticketing_app_api.models import Ticket, Project

class TicketSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ticket
        fields = ['id', 'ticket_url', 'description', 'user', 'type']

Вот мои взгляды:

from ticketing_app_api.models import Ticket
from ticketing_app_api.serializers import TicketSerializer
from rest_framework import generics
from rest_framework.decorators import api_view
from rest_framework.response import Response
# from rest_framework.reverse import reverse
from rest_framework import status


@api_view(['GET', 'POST'])
def ticket_list(request):
    """
    List all tickets, or creates a new ticket.
    """
    if request.method == 'GET':
        tickets = Ticket.objects.all()
        serializer = TicketSerializer(tickets, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = TicketSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class TicketDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Ticket.objects.all()
    serializer_class = TicketSerializer

Более чистым подходом было бы получить project_id при создании проекта, а затем просто отправить его при создании тикета. В этом случае ваш TicketSerializer должен также содержать проект:

class TicketSerializer(serializers.ModelSerializer):

    class Meta:
        model = Ticket
        fields = ["id", "ticket_url", "description", "user", "type", "project"]

и когда вы отправляете запрос на почту, вы должны указать, какой именно проект:

{
    "ticket_url": "http://ticket.com",
    "project": 1
}

В случае, если вы должны использовать project_code, вы можете установить проект при проверке данных:

class TicketSerializer(serializers.ModelSerializer):

    class Meta:
        model = Ticket
        fields = ["id", "ticket_url", "description", "user", "type"]

    def validate(self, attrs):
        attrs["project"] = Project.objects.get(
            project_code=self.initial_data.get("project_code")
        )
        return attrs
Вернуться на верх