Django 并在不同视图中向外部 API 发布请求
Posted
技术标签:
【中文标题】Django 并在不同视图中向外部 API 发布请求【英文标题】:Django and post request to an external API in different views 【发布时间】:2020-09-21 13:10:41 【问题描述】:所以我想创建一个 Django 应用程序,我的用户可以通过表单发布数据并向外部 API 发出发布请求,但在同一页面/视图中获得响应
例如,我有我的看法
class Home(TemplateView):
template_name: 'home/index.html'
我有我的 index.html:
<form id="formdata" >
<select id="options">
<option id="sku">Option 1</option>
<option id="sku2">Option 2</option>
</select>
<input name="number" type="text" id="number">
<select id="price">
<option id="price1">$5</option>
<option id="price2">%10</option>
</select>
<button type="button" data-loading-text="enviando..." onclick="submitInfo()">Send</button>
</form>
让我们忽略 HTML 可能是错误的事实,它是带有选择和输入字段的表单的基本结构,但请注意,我需要在发布请求中传递“产品”、“数字”和“价格”作为参数.
问题是当用户点击提交按钮时,他们向外部 api 发出发布请求,我知道我可以使用 fetch 使用 javascript 执行 int,但问题是我需要传递我的个人令牌密钥在正文参数中,我还想隐藏真正的 api url,用我的网站的 url 隐藏它,例如:www.myurl.com/my-api-call
所以我正在考虑创建一个带有发布请求的“external_api_view”,如下所示:
import requests
import time
from rest_framework import status
from rest_framework.response import Response
def external_api_view(request):
if request.method == "POST":
attempt_num = 0 # keep track of how many times we've retried
while attempt_num < MAX_RETRIES:
url = 'www.apiexternal.com/endpoint'
payload = 'Token':'My_Secret_Token','product':'product_select_in_form','price':'price_selected_in_form'
response = requests.post(url, data = payload)
if r.status_code == 200:
data = r.json()
return Response(data, status=status.HTTP_200_OK)
else:
attempt_num += 1
# You can probably use a logger to log the error here
time.sleep(5) # Wait for 5 seconds before re-trying
return Response("error": "Request failed", status=r.status_code)
else:
return Response("error": "Method not allowed", status=status.HTTP_400_BAD_REQUEST)
但我不知道如何将表单的输入传递到该视图中的问题,所以我可以发出发布请求并通过我的 index.html 文件上的 javascript 获得响应(显然添加了 javascript需要)
我什至不知道这是否可能,我正在考虑用 rest 框架做类似的事情,但我也不知道该怎么做
任何帮助将不胜感激:)
【问题讨论】:
【参考方案1】:首先在表单中添加一个动作属性和方法属性。然后添加一个 csrf 令牌以确保安全。还将名称属性添加到选择元素。
<form method="post" action="/external" id="formdata" >
% csrf_token %
<select name="options" id="options">
<option id="sku">Option 1</option>
<option id="sku2">Option 2</option>
</select>
<input name="number" type="text" id="number">
<select name="price" id="price">
<option id="price1">$5</option>
<option id="price2">%10</option>
</select>
<button type="button" data-loading-text="enviando..." onclick="submitInfo()">Send</button>
接下来为您添加的操作添加 url 路径。 urls.py:
from django.urls import path
from . import views
app_name = "main"
urlpatterns = [
...
path("external", views.external_api_view, name="home")
]
然后在views.py中获取输入值
import requests
import time
from rest_framework import status
from rest_framework.response import Response
def external_api_view(request):
if request.method == "POST":
attempt_num = 0 # keep track of how many times we've retried
while attempt_num < MAX_RETRIES:
url = 'www.apiexternal.com/endpoint'
payload = 'Token':'My_Secret_Token','product':request.POST.get("options"),'price':request.POST.get("price")
r = requests.post(url, data = payload)
if r.status_code == 200:
data = r.json()
return Response(data, status=status.HTTP_200_OK)
else:
attempt_num += 1
# You can probably use a logger to log the error here
time.sleep(5) # Wait for 5 seconds before re-trying
return Response("error": "Request failed", status=r.status_code)
else:
return Response("error": "Method not allowed", status=status.HTTP_400_BAD_REQUEST)
【讨论】:
以上是关于Django 并在不同视图中向外部 API 发布请求的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django admin 中向第三方外部 jQuery 插件提供 $
Python Django:在视图中向对象添加属性还是制作数据字典更好?