Django: 字节索引必须是整数或切片,而不是字符串错误。

huangapple go评论60阅读模式
英文:

Django: byte indices must be integers or slices, not str error

问题

我正在尝试使用 Webhook 从有效负载中获取一些数据,在我发送的响应中,我添加了应该与有效负载一起返回的元数据,以下是我如何做的(下面的代码),如果您仔细查看键,您会发现有一个名为meta的键,现在我正在尝试从我的 Webhook 视图中获取来自 meta 的一些数据,如下所示:

views.py webhook

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = request.body
    order_id = payload['meta']['order_id']
    print(order_id)
    return HttpResponse("testing...")

将响应发送给支付网关

@csrf_exempt
def process_payment(request, name, email, amount, order_id):
    auth_token = "FLWSECK_TEST-9efb9ee17d8afe40c6c890294a1163de-X"
    hed = {'Authorization': 'Bearer ' + auth_token}
    data = {
        "tx_ref": ''+str(math.floor(1000000 + random.random()*9000000)),
        "amount": amount,
        "currency": "USD",
        "order_id": order_id,
        "redirect_url": f"http://localhost:3000/service-detail/booking/confirmation/{order_id}",
        "payment_options": "card",
        "meta":{
            "order_id": order_id,
            "consumer_id": 23,
            "consumer_mac": "92a3-912ba-1192a"
        },
        "customer":{
            "email": email,
            "name": name,
            "order_id": order_id
        },
        "customizations":{
            "title": "ForecastFaceoff",
            "description": "Leading Political Betting Platform",
            "logo": "https://i.im.ge/2022/08/03m/FELzix.stridearn-high-quality-logo-circle.jpg"
        }
    }
    url = ' https://api.flutterwave.com/v3/payments'
    response = requests.post(url, json=data, headers=hed)
    response = response.json()
    link = response['data']['link']
    return redirect(link)

有效负载

{
  "event": "charge.completed",
  "data": {
    "id": 4136234873,
    "tx_ref": "6473247093",
    "flw_ref": "FLW-MOCK-b33e86ab2342316fec664110e8eb842a3c2f956",
    "device_fingerprint": "df38c8854324598c54e16feacc65348a5e446",
    "amount": 152,
    "currency": "USD",
    "charged_amount": 152,
    "app_fee": 5.78,
    "merchant_fee": 0,
    "processor_response": "Approved. Successful",
    "auth_model": "VBVSECUREertrCODE",
    "ip": "52.209.154.143",
    "narration": "CARD Transaction ",
    "status": "successful",
    "payment_type": "card",
    "created_at": "2023-02-06T11:19:45.000Z",
    "account_id": 685622,
    "customer": {
      "id": 1970338,
      "name": "destiny ",
      "phone_number": null,
      "email": "******@gmail.com",
      "created_at": "2023-02-06T11:19:45.000Z"
    },
    "card": {
      "first_6digits": "653188",
      "last_4digits": "2340",
      "issuer": "MASTERCARD  CREDIT",
      "country": "NG",
      "type": "MASTERCARD",
      "expiry": "49/32"
    }
  },
  "event.type": "CARD_TRANSACTION"
}

元数据甚至没有显示在有效负载中,必须在有效负载中显示才能获取其中发送的数据吗?

英文:

I am trying to get some data from a payload using a webhook, in the response that I sent along side I added the meta data that should return with the payload and this is how I did it (code below), if you take a close look at the keys, there I one called meta, now I am trying to get some of the data that is in the meta from my webhook view like this:

views.py webhook

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = request.body
    order_id = payload['meta']['order_id']
    print(order_id)
    return HttpResponse("testing...")

Sending the reponse to the payment gateway

@csrf_exempt
def process_payment(request, name, email, amount, order_id):
    auth_token = "FLWSECK_TEST-9efb9ee17d8afe40c6c890294a1163de-X"
    hed = {'Authorization': 'Bearer ' + auth_token}
    data = {
            "tx_ref":''+str(math.floor(1000000 + random.random()*9000000)),
            "amount":amount,
            "currency":"USD",
            "order_id":order_id,
            "redirect_url":f"http://localhost:3000/service-detail/booking/confirmation/{order_id}",
            "payment_options":"card",
            "meta":{
                "order_id":order_id,
                "consumer_id":23,
                "consumer_mac":"92a3-912ba-1192a"
            },
            "customer":{
                "email":email,
                "name":name,
                "order_id":order_id
            },
            "customizations":{
                "title":"ForecastFaceoff",
                "description":"Leading Political Betting Platform",
                "logo":"https://i.im.ge/2022/08/03m/FELzix.stridearn-high-quality-logo-circle.jpg"
                }
            }
    url = ' https://api.flutterwave.com/v3/payments'
    response = requests.post(url, json=data, headers=hed)
    response=response.json()
    link=response['data']['link']
    return redirect(link)

payload

{
  "event": "charge.completed",
  "data": {
    "id": 4136234873,
    "tx_ref": "6473247093",
    "flw_ref": "FLW-MOCK-b33e86ab2342316fec664110e8eb842a3c2f956",
    "device_fingerprint": "df38c8854324598c54e16feacc65348a5e446",
    "amount": 152,
    "currency": "USD",
    "charged_amount": 152,
    "app_fee": 5.78,
    "merchant_fee": 0,
    "processor_response": "Approved. Successful",
    "auth_model": "VBVSECUREertrCODE",
    "ip": "52.209.154.143",
    "narration": "CARD Transaction ",
    "status": "successful",
    "payment_type": "card",
    "created_at": "2023-02-06T11:19:45.000Z",
    "account_id": 685622,
    "customer": {
      "id": 1970338,
      "name": "destiny ",
      "phone_number": null,
      "email": "******@gmail.com",
      "created_at": "2023-02-06T11:19:45.000Z"
    },
    "card": {
      "first_6digits": "653188",
      "last_4digits": "2340",
      "issuer": "MASTERCARD  CREDIT",
      "country": "NG",
      "type": "MASTERCARD",
      "expiry": "49/32"
    }
  },
  "event.type": "CARD_TRANSACTION"
}

The metadata is not even showing in the payload, must it show up there in the payload before I can grab the data that is sent with it?

答案1

得分: 1

以下是您要的代码部分的中文翻译:

"meta" 数据不在 "payload" 字典中。首先尝试从 "payload" 中提取数据键,如下所示:

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = json.loads(request.body.decode("utf-8"))
    data = payload.get("data")
    if data:
        order_id = data.get("meta", {}).get("order_id")
        print(order_id)
    return HttpResponse("仅用于测试")

编辑:

如您在上面的评论中所描述的错误消息 JSONDecodeError: Expecting value: line 1 column 1 (char 0) 表明 json.loads() 期望以 JSON 字符串作为输入。

可能请求体为空。您可以通过在调用 json.loads() 之前打印 request.body 来检查它。

尝试这个:

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = json.loads(request.body.decode("utf-8"))
    data = payload.get("data")
    if data and "meta" in data:
        order_id = data.get("meta").get("order_id")
        print(order_id)
    else:
        print("在数据中未找到“meta”键或在“payload”中未找到数据")
        print(payload)
    return HttpResponse("仅用于测试")

这会告诉您是否在数据字典中存在 "meta",并在最后打印 payload 字典。

英文:

The meta data is not in the payload dictionary. At first try to extract the data key from the payload like this:

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = json.loads(request.body.decode("utf-8"))
    data = payload.get("data")
    if data:
        order_id = data.get("meta", {}).get("order_id")
        print(order_id)
    return HttpResponse("just testing")

Edit:

The error message
as you described above in comment JSONDecodeError: Expecting value: line 1 column 1 (char 0) indicates that json.loads() is expecting a JSON string as input.

It may be possible that request body is empty. You can check that by printing the request.body before calling json.loads().

Try this:

@csrf_exempt
@require_http_methods(['POST', 'GET'])
def webhook(request):
    payload = json.loads(request.body.decode("utf-8"))
    data = payload.get("data")
    if data and "meta" in data:
        order_id = data.get("meta").get("order_id")
        print(order_id)
    else:
        print("Meta key not found in data or data not found in payload")
        print(payload)
    return HttpResponse("just testing")

It would tell you whether the "meta" is present in data dictionary or not and also prints payload dict at the end.

答案2

得分: 0

request.body是字节而不是字典所以您需要将字符串加载为JSON

    payload = json.loads(request.body)
英文:

request.body is byte not a dict, so you need to load the string as JSON.

payload = json.loads(request.body)

huangapple
  • 本文由 发表于 2023年2月6日 19:25:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75360686.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定