如何在Django urlconf中匹配URL?
我正在实现一个叫做mercadopago的支付模块(类似于paypal),需要处理一个HTTP请求,这个请求会在有人付款时发送到我的网站(称为IPN),信息的URL格式如下:
POST /notifications?topic=payment&id=identificador-de-notificacion-de-pago
(每当有付款发生时,mercadopago会向我的网站发送一个POST请求)
但是我无法让这个请求与Django的URL系统匹配。我尝试了以下的URL:
url(r'^notifications$', 'views.notifications', name='notifications'),
我尝试了不同的组合,并查看了Apache的日志文件,结果出现了500错误。
处理这个URL的视图是:
@csrf_exempt
def IpnProxy(request, **kwargs):
mp = mercadopago.MP("*********", "*********")
paymentInfo = mp.get_payment_info(kwargs["id"])
if paymentInfo["status"] == 200:
return paymentInfo["response"]
else:
return None
我不确定是否需要配置信号或其他什么。
也许我理解错了,但mercadopago会向我的服务器发送POST请求,我无法更改这一点。这里是他们的文档 http://developers.mercadopago.com/documentation/instant-payment-notifications?lang=en_US 还有他们在Python中的示例项目: https://github.com/mercadopago/sdk-python/blob/master/examples/instant-payment-notifications/receive-ipn.py
2 个回答
在问号 ?
后面的内容就是一个叫做查询字符串的东西,它包含了请求的GET参数。这些参数并不包含在 urls.py
的网址模式里:
url(r'^notifications/$', view_notifications)
在视图中,可以通过request.GET
QueryDict
来获取这些 GET
参数:
def view_notifications(request):
topic = request.GET.get('topic')
print topic
相关内容:
你在Django中对POST请求的参数编码方式不对。POST请求的参数应该放在请求的主体里。建议你查看一下Django的请求和响应对象的文档。如果你真的想用你提供的那个网址,就需要用GET请求,而不是POST请求。
--- 编辑 ---
试试下面的方法:在你的urls.py文件中,导入notification之后。
url(r'^notification$', notification, name='notification')
在你的settings.py文件中:
APPEND_SLASH=False
你几乎肯定还需要关闭CSRF保护,因为你不会有CSRF cookie。
你可以这样获取参数:
def notification(request, **kwargs):
body = "topic = '{0}'\nid = '{1}'\n".format(request.GET.get('topic'), request.GET.get('id'))
response = HttpResponse(body, content_type="text/plain")
return response
测试后我们得到:
hackworth:~$ curl -X POST "http://127.0.0.1:8000/notification?topic=payment&id=identificador-de-notificacion-de-pago"
topic = 'payment'
id = 'identificador-de-notificacion-de-pago'
以上所有做法都不太好,因为POST请求通常会有一个主体,而Django并不期望在POST的URL中出现查询参数。此外,由于需要关闭CSRF保护来让这个工作,这样做会带来安全隐患。
根据文档的描述,你会从mercadopago那里收到一个URL,然后用GET请求去获取。并不清楚他们会给你发送一个带查询参数的POST请求。