You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Django Forms调用API遇阻,终端脚本可正常运行求助

解决Django Form调用Nutritionix API的前端提交问题

嘿,我来帮你搞定这个问题!从你说的情况来看,终端硬编码的脚本能成功调用API,但用Django表单提交就不行,大概率是请求方式不对、前端数据传递有误或者Django视图处理逻辑有漏洞。咱们一步步拆解排查:

先修正你终端脚本里的小问题

你原来的脚本里字典有重复的query键,而且用了body传递参数,但Nutritionix的/v2/search/instant接口是GET请求,参数应该放在URL的查询字符串里,不是请求体。修正后的终端脚本应该是这样:

import requests
import json

url = "https://trackapi.nutritionix.com/v2/search/instant"
headers = {
    'x-app-id': "ff0ccea8",
    'x-app-key': "605660a17994344157a78f518a111eda"
}
params = {'query': "apple"}  # 用params传递GET参数
response = requests.get(url, headers=headers, params=params)

if response.status_code == 200:
    print(json.dumps(response.json(), indent=2))
else:
    print(f"请求失败:{response.status_code}")
    print(response.text)

Django端的完整实现步骤

1. 定义表单类

先在你的app里创建一个表单,用来接收前端的搜索关键词:

# forms.py
from django import forms

class FoodSearchForm(forms.Form):
    query = forms.CharField(
        label='搜索食物',
        max_length=100,
        widget=forms.TextInput(attrs={'placeholder': '比如:apple'})
    )

2. 编写视图函数处理表单提交和API调用

视图里要做的事:接收表单数据、验证、调用API、返回结果给前端。注意一定要用GET请求调用Nutritionix API,并且通过后端代理(避免前端跨域问题):

# views.py
import requests
from django.shortcuts import render
from django.conf import settings
from .forms import FoodSearchForm

def food_search(request):
    results = None
    error_msg = None

    if request.method == 'POST':
        form = FoodSearchForm(request.POST)
        if form.is_valid():
            query = form.cleaned_data['query']
            # 从settings里取密钥(别硬编码在代码里!)
            headers = {
                'x-app-id': settings.NUTRITIONIX_APP_ID,
                'x-app-key': settings.NUTRITIONIX_APP_KEY
            }
            params = {'query': query}
            api_url = "https://trackapi.nutritionix.com/v2/search/instant"

            try:
                response = requests.get(api_url, headers=headers, params=params)
                response.raise_for_status()  # 抛出HTTP错误
                results = response.json()
            except requests.exceptions.RequestException as e:
                error_msg = f"API调用失败:{str(e)}"
                print(error_msg)  # 后台打印错误方便排查
    else:
        form = FoodSearchForm()

    return render(request, 'food_search.html', {
        'form': form,
        'results': results,
        'error_msg': error_msg
    })

3. 配置settings.py(安全起见)

把API密钥放在settings里,不要直接写在视图里:

# settings.py
NUTRITIONIX_APP_ID = "ff0ccea8"
NUTRITIONIX_APP_KEY = "605660a17994344157a78f518a111eda"

4. 前端模板(food_search.html)

表单要加{% csrf_token %},不然Django会拒绝POST请求;同时展示返回的结果:

<!-- templates/food_search.html -->
<!DOCTYPE html>
<html>
<head>
    <title>食物营养搜索</title>
</head>
<body>
    <h1>搜索食物营养信息</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">搜索</button>
    </form>

    {% if error_msg %}
        <p style="color: red;">{{ error_msg }}</p>
    {% endif %}

    {% if results %}
        <h2>搜索结果</h2>
        {% if results.common %}
            <h3>常见食物</h3>
            <ul>
                {% for food in results.common %}
                    <li>{{ food.food_name }} - {{ food.serving_qty }} {{ food.serving_unit }}</li>
                {% endfor %}
            </ul>
        {% endif %}
        {% if results.branded %}
            <h3>品牌食物</h3>
            <ul>
                {% for food in results.branded %}
                    <li>{{ food.brand_name }} - {{ food.food_name }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    {% endif %}
</body>
</html>

常见坑点排查

  1. 请求方式错误:Nutritionix的这个接口只接受GET请求,别用POST传body,否则会返回400错误。
  2. CSRF令牌缺失:前端表单必须加{% csrf_token %},否则Django会返回403 Forbidden。
  3. 跨域问题:不要让前端直接调用Nutritionix API,浏览器会因为CORS政策阻止跨域请求,必须通过Django后端代理。
  4. 密钥安全:永远不要把API密钥提交到代码仓库,用settings配置+环境变量是更安全的做法。
  5. 错误处理:一定要捕获API请求的异常,比如网络错误、HTTP错误,方便排查问题。

内容的提问来源于stack exchange,提问作者Gage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:27:07