Omar Gonzales
Omar Gonzales

Reputation: 4008

How to modify serialized attributes of objects in Django?

I need to change the field product to name of my OrderItem objects because of how Google Enhanced Ecommerce requiers the data to be processed.

Requiered Fields for Google Analytics Ecommerce:

https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#product-data

Working example

https://developers.google.com/tag-manager/enhanced-ecommerce#purchases

As said before, my model has this field as product but Google needs it to be named name instead,

is it possible to change it in the view? Or do I need to change it somehow in HTML using Javascript?

view

def thanks_deposit_payment(request):
    order_number = Order.objects.latest('id').id

    total = Order.objects.latest('id').total

    costo_despacho = Order.objects.latest('id').shipping_cost

    order_items = OrderItem.objects.filter(order=Order.objects.latest('id'))


    order_items = serialize('json', order_items, fields=['id', 'sku', 'product', 'price', 'size', 'quantity'])


    response = render(request, 'thanks_deposit_payment.html', dict(order_number=order_number, total=total,
                                                               order_items=order_items, costo_despacho=costo_despacho))
    return response

template:

<script>
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            event: 'eec.purchase',
            ecommerce: {
                currencyCode: 'PEN',
                purchase: {
                    actionField: {
                        id: {{ order_number }},
                        affiliation: 'Stickers Gallito E-Commerce',
                        revenue: {{ total }},
                        shipping: {{ costo_despacho }},
                        coupon: ''
                    },
                    products: JSON.parse('{{ order_items | safe }}')
                },

            }
        });
    </script>

models.py

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.CharField(max_length= 200)
    sku = models.CharField(max_length=20)
    quantity = models.CharField(max_length= 200)
    size = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name= 'PEN Price')
    file = models.FileField(upload_to='files', blank=True, null=True)
    comment = models.CharField(max_length=200, blank=True, null=True, default='')
    uploaded_at = models.DateTimeField(auto_now_add=True)

UPDATE 1

Thanks to ruddra answer I get 'product' change to 'name', but the dataLayer shows:

Uncaught SyntaxError: missing ) after argument list

products: JSON.parse('[{'sku': 'M1', 'quantity': '10', 'size': 'varios', 'price': '3.00', 'name': 'Sobre con muestras'}]')

It only happens If I change the view with what the suggestion from that answers.

Upvotes: 0

Views: 211

Answers (2)

ruddra
ruddra

Reputation: 51998

Its possible to change in view, you can do it like this:

order_items = serialize('json', order_items, fields=['id', 'product', 'price'])  # the fields needed for products

order_items_json = json.loads(order_items)
products_list = []
for item in order_items_json:
    product_dict = item.get('fields')
    product_dict['name'] = product_dict.pop('product')
    products_list.append(product_dict)

return render('template_name.html', dict(order_number=order_number, total=total, order_items=json.dumps(products_list), costo_despacho=costo_despacho))

Upvotes: 1

Brad Martsberger
Brad Martsberger

Reputation: 1967

You can annotate the queryset so that the result has a name field

q = Q(order=Order.objects.latest('id'))
order_items = OrderItem.objects.filter(q).annotate(name=F('product'))

Then replace product with name in your serializer fields.

Edit: Thanks to the commenters for pointing out that this doesn't actually work because Django's serialize will only serialize attribute that are fields on the model. You'd have to write a custom serializer as well.

Upvotes: 2

Related Questions