Есть ли способ захватить определенные «поля» из запроса.данные, отправленные в API-интерфейс Django REST framework методом POST

#python #django #django-rest-framework

Вопрос:

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

Как только я свяжусь с запросом.данные project_code в поле project_code модели проекта я хочу сохранить объект модели билета в базе данных. Внутри моей модели билета есть поле под названием проект, которое связано с внешним ключом к модели проекта.

Таким образом, по сути, код проекта внутри запроса POST.данные необходимо использовать для сохранения моей модели билета в базе данных с правильным внешним ключом модели проекта.

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

 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
 

Ответ №1:

Более чистый подход состоял бы в том, чтобы получить 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
 

Комментарии:

1. В случае использования кода проекта я получаю сообщение об ошибке «Метод публикации не разрешен».

2. @RubenAdriaanse можете ли вы обновить свой вопрос с помощью конфигурации URL-адресов ? Вы должны делать ЗАПИСЬ в своем ticket_list представлении