Есть ли способ получить определенные "поля" из 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