如何在Django urlconf中匹配URL?

4 投票
2 回答
654 浏览
提问于 2025-04-18 13:54

我正在实现一个叫做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 个回答

2

在问号 ? 后面的内容就是一个叫做查询字符串的东西,它包含了请求的GET参数。这些参数并不包含在 urls.py 的网址模式里:

url(r'^notifications/$', view_notifications)

在视图中,可以通过request.GET QueryDict 来获取这些 GET 参数:

def view_notifications(request):
    topic = request.GET.get('topic')
    print topic

相关内容:

2

你在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请求。

撰写回答