Django 和 DRF 如何在保存之前使用 POST 请求到 API 的字段?

Django and DRF How to use the fields of a POST request to the API before saving?

我安装了 Django 1.10 和 Django REST 框架。

我很好地收到了 POST 请求,但我希望在创建内容之前使用这些字段执行一些任务,我的 views.py 文件中有以下内容

from rest_framework.decorators import detail_route
from rest_framework import serializers
from suds.client import Client
import base64
from . import views

# Create your views here.

from cfdipanel.models import Report, Invoice, UserProfile
from cfdi.serializers import ReportSerializer, InvoiceSerializer, UserProfileSerializer


class ReportViewSet(viewsets.ModelViewSet):
    queryset = Report.objects.all()
    serializer_class = ReportSerializer

    @detail_route(methods=['post'])
    def set_invoice(self, request, pk=None):

        #get report object
        my_report = self.get_object()
        serializer = InvoiceSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(report=my_report)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是我文件的一个片段serializer.py

from rest_framework import serializers
from cfdipanel.models import Report, Invoice, UserProfile

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ('user', 'karma')


class InvoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invoice
        fields = ('uuid', 're', 'rr', 'tt',
                  'emision_date', 'type_invoice', 'status', 'owner')


class ReportSerializer(serializers.ModelSerializer):
    owner = UserProfileSerializer(read_only=True)
    ownerId = serializers.PrimaryKeyRelatedField(write_only=True,
                                                 queryset=UserProfile.objects.all(),
                                                 source='owner')
    invoices = InvoiceSerializer(many=True,
                                 read_only=True,
                                 source='invoice_set')

    class Meta:
        model = Report
        fields = ('id', 'title', 'body', 'owner', 'ownerId', 'invoices')

另一个是 models.py

的片段
class Invoice(models.Model):
    owner = models.ForeignKey(UserProfile)
    report = models.ForeignKey(Report)
    uuid = models.CharField(max_length=36)
    emision_date = models.CharField(max_length=28)
    re = models.CharField(max_length=13)
    rr = models.CharField(max_length=13)
    type_invoice = models.CharField(max_length=10)
    status = models.CharField(max_length=2, blank=True)
    tt = models.DecimalField(max_digits=19, decimal_places=9,
                                default=Decimal(0))
    def __str__(self):
        return self.uuid

状态字段为空,要填充它我想在保存字段之前在 view.py 中执行类似于以下代码的操作:

url = 'https://an-api.com/ConsultService.svc?wsdl'
client = Client(url)
string = "?re=" + re + "&rr=" + rr + \
             "&tt=" + tt + "&id=" + uuid

response = client.service.Consulta(string)

# Create content for field status
status = response.Status

从网络服务获得响应后,保存并创建发票内容。

request.datareturns一个dict实例,InvoiceSerializerreturns一个Invoice"instance",所以你可以修改反序列化之前或之后的数据。使用:

data = request.data
data['field'] = 'foo'

serializer = InvoiceSerializer(data=request.data)
serializer.object.invoice_field = 'foo'

对于 DRF 3

serializer = InvoiceSerializer(data=request.data)
serializer.save(invoice_field ='foo')

这可能对您有帮助:

尝试打印 request.data

您可以使用 request.data['keyName'] 访问通过请求发送的每个字段,它将打印发送到名为 keyName.so 的键中的值,您可以操纵请求,然后将其发送到序列化程序。