简体   繁体   English

Django 并在不同视图中将请求发布到外部 API

[英]Django and post request to an external API in different views

So i want to create a Django App where my users can post data through a form and make a post request to an external API, but getting the response in the same page/view所以我想创建一个 Django 应用程序,我的用户可以通过表单发布数据并向外部 API 发出发布请求,但在同一页面/视图中获得响应

For example, i have my view例如,我有我的看法

class Home(TemplateView):
    template_name: 'home/index.html'

And i have my 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>

Let's ignore the fact HTML may be wrong, it is a basic structure of a form with selects and input field, but note that i need to pass "product", "number" and "price" as parameters in the post request.让我们忽略 HTML 可能是错误的事实,它是带有选择和输入字段的表单的基本结构,但请注意,我需要在发布请求中传递“产品”、“数量”和“价格”作为参数。

The thing is that when the user clics on the submit button, they make a post request to an external api, i know i can do int with JavaScript using fetch, but the thing is that i need to pass my personal Token Key in the body params, also i'd like to hide the real api url hiding it with an url of my website, for example: www.myurl.com/my-api-call问题是当用户点击提交按钮时,他们向外部 api 发出发布请求,我知道我可以使用 fetch 对 JavaScript 进行 int,但问题是我需要在正文中传递我的个人令牌密钥参数,我也想隐藏真正的 api url 用我的网站的 url 隐藏它,例如:www.myurl.com/

So i'm thinking about creating a "external_api_view" with post request, something like this:所以我正在考虑使用发布请求创建一个“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)

But not i have the problem that i don't know how to pass inputs of the form into that view, so i can make the post request and get the response through javascript on my index.html file (adding obviously the javascript needed)但不是我的问题是我不知道如何将表单的输入传递到该视图中,所以我可以发出发布请求并通过我的 index.html 文件上的 javascript 获得响应(显然需要添加 ZDE9B9ED78D7E2E19DCEEFFEE780E2)

I don't even know if this is possible, i was thinking in doing something like so with rest framework, but also i have no idea how to我什至不知道这是否可能,我正在考虑使用 rest 框架做类似的事情,但我也不知道如何

Any help would be really appreciated:)任何帮助将非常感激:)

First add an action attribute and method attribute to your form.首先在表单中添加一个动作属性和方法属性。 Then add a csrf token for security.然后添加一个 csrf 令牌以确保安全。 Also add name attributes to the select elements.还将名称属性添加到 select 元素。

<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>

Next add the url path for the action you added.接下来为您添加的操作添加 url 路径。 urls.py:网址.py:

from django.urls import path
from . import views

app_name = "main"   

urlpatterns = [
    ...
    path("external", views.external_api_view, name="home")

]

Then get the input values in views.py然后在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM