Skip to main content
 首页 » 编程设计

python之序列化程序在 Javascript 中添加了不必要的字段

2024年11月24日33rubylouvre

我需要从 Django Queryset 生成一个非常干净的 JS 数组结构。为此,我使用了序列化程序。

However, they final array has extra field that may be causing problems with Google Analytics requested format.

Google Analytics 请求的格式:

Notice the structure of the products Array

<script> 
// Send transaction data with a pageview if available 
// when the page loads. Otherwise, use an event when the transaction 
// data becomes available. 
dataLayer.push({ 
  'ecommerce': { 
    'purchase': { 
      'actionField': { 
        'id': 'T12345',                         // Transaction ID. Required for purchases and refunds. 
        'affiliation': 'Online Store', 
        'revenue': '35.43',                     // Total transaction value (incl. tax and shipping) 
        'tax':'4.90', 
        'shipping': '5.99', 
        'coupon': 'SUMMER_SALE' 
      }, 
      'products': [{                            // List of productFieldObjects. 
        'name': 'Triblend Android T-Shirt',     // Name or ID is required. 
        'id': '12345', 
        'price': '15.25', 
        'brand': 'Google', 
        'category': 'Apparel', 
        'variant': 'Gray', 
        'quantity': 1, 
        'coupon': ''                            // Optional fields may be omitted or set to empty string. 
       }, 
       { 
        'name': 'Donut Friday Scented T-Shirt', 
        'id': '67890', 
        'price': '33.75', 
        'brand': 'Google', 
        'category': 'Apparel', 
        'variant': 'Black', 
        'quantity': 1 
       }] 
    } 
  } 
}); 
</script> 

dataLayer product 序列化器生成的数组:

包含序列化程序的 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', 'name', '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 

模板中的数据层:

这是生成需要更改的 Products 数组的行:

 products: JSON.parse('{{ order_items | safe }}') 

模板中完整的JS代码:

{% block data_layer %} 
 
<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> 
 
{% endblock %} 

如何匹配 Google 预期的格式?

请您参考如下方法:

您没有指定什么是serializer,但我推测它来自from django.core import serializers。根据 documentation ,实际上它将对象列表映射到这种布局:

[ 
    { 
        "pk": "4b678b301dfd8a4e0dad910de3ae245b", 
        "model": "sessions.session", 
        "fields": { 
            "expire_date": "2013-01-16T08:16:59.844Z", 
            ... 
        } 
    } 
] 

我没有看到自定义序列化器行为的方法, 但您始终可以手动重新序列化自己。 例如,使用 json 包,您可以这样做:

# at the top of the script 
import json 
 
# ... 
 
def thanks_deposit_payment(request):     
    # ... 
 
    order_items_serialized = serialize('json', order_items, fields=['id', 'sku', 'name', 'price', 'size', 'quantity']) 
 
    # convert the serialized string to a Python object 
    order_items_obj = json.loads(order_items_serialized) 
 
    # define the target mapping 
    def mapper(p): 
        return { 
            'id': p['pk'], 
            'sku': p['fields']['sku'], 
            'name': p['fields']['name'], 
            # ... and so on ... 
        } 
 
    # re-map and re-serialize the items 
    order_items = json.dumps(list(map(mapper, order_items_obj)))