В данном уроке мы научимся как передавать дополнительные данные в сериализатор перед их сохранением в базе данных.
Введение
При использовании обычных форм Django существует общий шаблон, в котором мы сохраняем форму с помощью commit = False, а затем передаем некоторые дополнительные данные экземпляру перед сохранением их в базе данных, например:
form = InvoiceForm(request.POST)
if form.is_valid():
invoice = form.save(commit=False)
invoice.user = request.user
invoice.save()
Это очень полезно, потому что мы можем сохранить требуемую информацию, используя только один запрос к базе данных, а также позволяет обрабатывать столбцы, не допускающие значения NULL, которые не были определены в форме.
Чтобы смоделировать этот шаблон с помощью сериализатора Django REST Framework, вы можете сделать что-то вроде этого:
serializer = InvoiceSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user)
Вы также можете передать сразу несколько параметров:
serializer = InvoiceSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user, date=timezone.now(), status='sent')
Пример использования с APIView
В этом примере я создал приложение с именем core.
models.py
from django.contrib.auth.models import User
from django.db import models
class Invoice(models.Model):
SENT = 1
PAID = 2
VOID = 3
STATUS_CHOICES = (
(SENT, 'sent'),
(PAID, 'paid'),
(VOID, 'void'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='invoices')
number = models.CharField(max_length=30)
date = models.DateTimeField(auto_now_add=True)
status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES)
amount = models.DecimalField(max_digits=10, decimal_places=2)
serializers.py
from rest_framework import serializers
from core.models import Invoice
class InvoiceSerializer(serializers.ModelSerializer):
class Meta:
model = Invoice
fields = ('number', 'amount')
views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from core.models import Invoice
from core.serializers import InvoiceSerializer
class InvoiceAPIView(APIView):
def post(self, request):
serializer = InvoiceSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(user=request.user, status=Invoice.SENT)
return Response(status=status.HTTP_201_CREATED)
Пример использования с ViewSet
Очень похожий пример с теми же моделями.py и serializers.py, что и в предыдущем примере.
views.py
from rest_framework.viewsets import ModelViewSet
from core.models import Invoice
from core.serializers import InvoiceSerializer
class InvoiceViewSet(ModelViewSet):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer
def perform_create(self, serializer):
serializer.save(user=self.request.user, status=Invoice.SENT)