laur
laur

Reputation: 500

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

I have an installation of Django 1.10 and Django REST framework.

I am getting POST requests well, but I would like it before the content is created, doing some tasks with the fields, I have the following in my views.py file

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)

And this a fragment of my file 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')

And this other is a snippet of 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

The status field comes empty, to fill it I want to do something similar to the following code in view.py before the fields are saved:

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

And after you get the response from the webservice then save and create the Invoice content.

Upvotes: 2

Views: 4959

Answers (2)

Piyush S. Wanare
Piyush S. Wanare

Reputation: 4933

This may help you:

Try to print request.data

You can access the each field send via request using request.data['keyName'] it will print the value send in key called keyName.so that you can manupulate the request and then sent it to serializer.

Upvotes: 1

arcegk
arcegk

Reputation: 1480

request.datareturns a dict instance, and InvoiceSerializer returns an Invoice "instance", so you can modify the data before of after deserializing it. using:

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

or

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

for DRF 3

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

Upvotes: 1

Related Questions