Create serialization with data from two tables

Asked

Viewed 26 times

-1

Good evening guys, I need help to be able to serialize the data according to "Desired result" but I’m only getting the result of the image "Result I’m getting", someone can help me?

Thank you!

Result that I am achieving Resultado que estou conseguindo

Desired result

Resultado desejado

py.models

from django.db import models


class CartItem(models.Model):
    cart = models.ForeignKey("Checkout", on_delete=models.CASCADE, verbose_name='Checkout', related_name="cart")
    item = models.ForeignKey("Product", on_delete=models.CASCADE, related_name="cartItens")
    quantity = models.CharField(max_length=5, verbose_name="Quantidade")
    line_item_total = models.CharField(max_length=5, blank=True)

    class Meta:
        verbose_name = 'Itens dos Checkout'

    def __str__(self):
        return '{} - {}x {}'.format(self.cart, self.quantity, self.item)


class Checkout(models.Model):
    id = models.IntegerField(primary_key=True, verbose_name="ID")
    products = models.ManyToManyField("Product", through=CartItem, related_name='tracks')
    total_amount = models.DecimalField(max_digits=50, decimal_places=2, default=0.00)
    total_amount_with_discount = models.DecimalField(max_digits=50, decimal_places=2, default=0.00)
    total_discount = models.DecimalField(max_digits=50, decimal_places=2, default=0.00)

    class Meta:
        verbose_name = 'Checkout'

    def __str__(self):
        return 'Pedido: {}'.format(self.id)


class Product(models.Model):
    id = models.IntegerField(primary_key=True, verbose_name="ID")
    title = models.CharField(max_length=50, verbose_name="Nome do produto")
    description = models.TextField(max_length=200, verbose_name="Descrição")
    price = models.DecimalField('Preço', decimal_places=0, max_digits=8)
    is_gift = models.BooleanField(default=False, verbose_name="Brinde")
    created_at = models.DateField(auto_now_add=True, auto_now=False, verbose_name="Data de criação")

    class Meta:
        ordering = ['id']
        verbose_name = 'Produto'
        verbose_name_plural = 'Produtos'
        unique_together = (('id', 'title'),)

    def __str__(self):
        return '{}'.format(self.title)

py serializers.

from rest_framework import serializers
from .models import Checkout, CartItem, Product


class CheckoutSerializer(serializers.ModelSerializer):

    class Meta:
        model = Checkout
        fields = ['total_amount', 'total_amount_with_discount','total_discount', 'products']


class CartItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = CartItem
        fields = ['cart', 'item', 'quantity','line_item_total']


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'title', 'description','price', 'is_gift']



py views.

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework import viewsets, permissions
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from apps.checkout.models import Checkout, CartItem, Product
from apps.checkout.serializers import CheckoutSerializer


class JSONResponse(HttpResponse):
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)


@csrf_exempt
def checkout(request):
    if request.method == 'GET':
        checkout = Checkout.objects.all()
        serializer = CheckoutSerializer(checkout, many=True)
        return JSONResponse(serializer.data)

    elif request.method == 'POST':
        data = JSONParser().parse(request)

        total_amount = 0
        total_amount_with_discount = total_amount - 200
        total_discount = 200

        checkout = Checkout

        for item in data['products']:

            product_id = item['id']
            product_quantity = item['quantity']


            produto = Product.objects.get(id=product_id)

            unit_amount = int(produto.price)
            is_gift = produto.is_gift

            # Valor total
            amount_item = unit_amount * product_quantity

            # Soma ao valor total do pedido
            total_amount = total_amount + amount_item


            checkout.total = total_amount
            checkout.save()


        serializer = CheckoutSerializer(data=data)

        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data, status=201)
        return JSONResponse(serializer.errors, status=400)


py.

from django.urls import path
from apps.checkout.views import checkout


urlpatterns = [
    path('', checkout),
    #path('<str:username>', funcionario_detalhes),
]

1 answer

0


Nesting serializers is easier than it looks. I’ll give you a general example, and you can delve deeper in that documentation.

Nesting is when you have a model, which has to be "called", in the serialization of another model.

The serializer of the model that must be "pulled" by the other must be declared before. Just below it, the serializer of the model you want to use as the main one, should call the serializer of the other model, and add it to the Fields. This example comes from the documentation.

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ['order', 'title', 'duration']

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)


    class Meta:
        model = Album
        fields = ['album_name', 'artist', 'tracks']

Many serves to receive more than one value, and read_only can be disabled if you create and update your templates within the serializer.

See, the Albumserializer "calls" the secondary serializer, the response of this serializer will be included as a normal field. Like I said, it’s a general idea, but it can be applied to your problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.