在本教程中,你将学习如何在将数据保存到数据库之前,向你的序列化器传递额外的数据。
简介
在使用普通的Django表单时,有这样一种常见的模式:我们用commit=False 保存表单,然后在保存到数据库之前向实例传递一些额外的数据,像这样:
form = InvoiceForm(request.POST)
if form.is_valid():
invoice = form.save(commit=False)
invoice.user = request.user
invoice.save()
这是非常有用的,因为我们可以只用一个数据库查询来保存所需的信息,而且它还可以处理表单中没有定义的非空列。
使用Django REST框架的序列化器来模拟这种模式,你可以这样做:
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的例子
非常类似的例子,使用与前一个例子相同的models.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)