GET API 在浏览器中显示 KeyError,但在 Postman 中工作
Posted
技术标签:
【中文标题】GET API 在浏览器中显示 KeyError,但在 Postman 中工作【英文标题】:GET API showing KeyError in browser, but working in Postman 【发布时间】:2021-03-01 02:43:57 【问题描述】:我遇到了一个奇怪的问题,我创建的 GET API 在 Postman 中运行良好,但在浏览器中输入时无法在该特定 URL 上运行。
下面是 Postman 中成功显示的输入和输出的样子:Trying API in Postman
这是我的浏览器上显示的错误:Error in browser
我在 React 中也遇到了这个关于 CORS 标头的错误,即使我已经添加了代码来尝试处理这个问题:Error in React about CORS
这是 Django 中 settings.py 中的代码:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Prediction',
'rest_framework',
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
这是 Django 中 local_settings.py 中的代码:
#########################################
## IMPORT LOCAL SETTINGS ##
#########################################
try:
from .local_settings import *
except ImportError:
pass
DATABASES =
'default':
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': '127.0.0.1',
'PORT': '5432',
#################################################################
## (CORS) Cross-Origin Resource Sharing Settings ##
#################################################################
CORS_ORIGIN_ALLOW_ALL = True
我还尝试在 React 中的 index.js 中添加此代码来处理 CORS 标头问题,但它不起作用:
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) =>
res.header('Access-Control-Allow-Origin', '*');
next();
);
app.get('/jokes/random', (req, res) =>
request(
url: 'https://joke-api-strict-cors.appspot.com/jokes/random'
,
(error, response, body) =>
if (error || response.statusCode !== 200)
return res.status(500).json(
type: 'error',
message: err.message
);
res.json(JSON.parse(body));
)
);
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on $PORT`));
这是 React 中 App.js 中的代码:
import logo from './logo.svg';
import './App.css';
import useState from 'react';
import axios from 'axios';
function App()
const [json_response1, set_json_response1] = useState("1st algorithm - List of similar events");
function request_json_response()
axios.get('http://127.0.0.1:8000/api/get_events_1st_alg',
data:
"ID": "User_ID1"
).then(function (response)
// handle success
set_json_response1(response);
);
return (
<div className="App">
<header className="App-header">
<img src=logo className="App-logo" />
<p>
json_response1
</p>
<button onClick=request_json_response>
Generate events for user
</button>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
export default App;
这是 Django 中的 views.py 中的代码:
class get_events_1st_alg(APIView):
def get(self, request, format=None):
"""
data = request.data
banana_dictionary = 'banana':17
return Response(banana_dictionary, status=status.HTTP_201_CREATED)
"""
import pandas as pd
import numpy as np
import psycopg2
import sqlalchemy
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.metrics import pairwise_distances
import requests
from sqlalchemy import create_engine
engine = create_engine('postgresql://postgres:postgres@localhost/postgres')
# pd.read_sql_query('''SELECT * FROM arts_user_interaction LIMIT 5;''', engine)
events = pd.read_sql_query('''SELECT * FROM arts_event;''', engine)
Ratings = pd.read_sql_query('''SELECT * FROM arts_user_interaction;''', engine)
Mean = Ratings.groupby(by="User_ID", as_index = False)['User Rating'].mean()
Rating_avg = pd.merge(Ratings, Mean, on = "User_ID")
Rating_avg['adg_rating']=Rating_avg['User Rating_x']-Rating_avg['User Rating_y']
check = pd.pivot_table(Rating_avg,values='User Rating_x',index='User_ID',columns='Event_ID')
final = pd.pivot_table(Rating_avg,values='adg_rating',index='User_ID',columns='Event_ID')
final_event = final.fillna(final.mean(axis=0))
final_user = final.apply(lambda row: row.fillna(row.mean()), axis=1)
cosine = cosine_similarity(final_event)
np.fill_diagonal(cosine, 0 )
similarity_with_event =pd.DataFrame(cosine,index=final_event.index)
similarity_with_event.columns=final_user.index
def find_n_neighbours(df,n):
order = np.argsort(df.values, axis=1)[:, :n]
df = df.apply(lambda x: pd.Series(x.sort_values(ascending=False)
.iloc[:n].index,
index=['top'.format(i) for i in range(1, n+1)]), axis=1)
return df
sim_user_30_e = find_n_neighbours(similarity_with_event,30)
def get_user_similar_events( user1, user2 ):
common_events = Rating_avg[Rating_avg.User_ID == user1].merge(
Rating_avg[Rating_avg.User_ID == user2],
on = "Event_ID",
how = "inner" )
return common_events.merge(events, on ='Event_ID')
a = get_user_similar_events('User_ID10','User_ID220')
a = a.reindex(columns= ['User Rating_x_x','User Rating_x_y','Name'])
Rating_avg = Rating_avg.astype("Event_ID": str)
Movie_user = Rating_avg.groupby(by = 'User_ID')['Event_ID'].apply(lambda x:','.join(x))
def User_item_score1(user):
Movie_seen_by_user = check.columns[check[check.index==user].notna().any()].tolist()
a = sim_user_30_e[sim_user_30_e.index==user].values
b = a.squeeze().tolist()
d = Movie_user[Movie_user.index.isin(b)]
l = ','.join(d.values)
Movie_seen_by_similar_users = l.split(',')
Movies_under_consideration = list(set(Movie_seen_by_similar_users)-set(list(map(str, Movie_seen_by_user))))
Movies_under_consideration = list(map(str, Movies_under_consideration))
score = []
for item in Movies_under_consideration:
c = final_event.loc[:,item]
d = c[c.index.isin(b)]
f = d[d.notnull()]
avg_user = Mean.loc[Mean['User_ID'] == user,'User Rating'].values[0]
index = f.index.values.squeeze().tolist()
corr = similarity_with_event.loc[user,index]
fin = pd.concat([f, corr], axis=1)
fin.columns = ['adg_score','correlation']
fin['score']=fin.apply(lambda x:x['adg_score'] * x['correlation'],axis=1)
nume = fin['score'].sum()
deno = fin['correlation'].sum()
final_score = avg_user + (nume/deno)
score.append(final_score)
data = pd.DataFrame('Event_ID':Movies_under_consideration,'score':score)
top_5_recommendation = data.sort_values(by='score',ascending=False).head(5)
Movie_Name = top_5_recommendation.merge(events, how='inner', on='Event_ID')
Movie_Names = Movie_Name.Name.values.tolist()
return Movie_Names
# user = input("Enter the user id to whom you want to recommend : ")
data = request.data
user = ""
for i, v in data.items():
user = str(v)
predicted_movies = User_item_score1(user)
return Response(predicted_movies, status=status.HTTP_201_CREATED)
我真的不知道我在做什么,因为我只是在网上学习一堆教程,所以如果有人可以帮助解决浏览器中的 API 问题和浏览器中的 CORS 的 React 问题,我会很高兴的好吧。非常感谢!
【问题讨论】:
【参考方案1】:问题是 GET 请求不应该有正文(它没有被 axios 指定/支持)。在 axios 存储库中查看此问题:link。
请从数据更改为参数:
axios.get('http://127.0.0.1:8000/api/get_events_1st_alg', params: "ID":"User_ID1")
并在 DRF 中访问它,例如:
user = request.query_params.get("ID")
您的 CORS 配置正常。
【讨论】:
您好!非常感谢您的回复!所以我尝试了你建议的两种方法,但我最终在邮递员和浏览器中都得到了一个 KeyError 。但是,当我在 views.py 中以原始方式而不是在 index.js 中执行 query_params(并在 index.js 中保留参数而不是数据)时,它在 Postman 中有效,但在浏览器中无效。 当我尝试启动 React 服务器时,它说我有一个“TypeError: Cannot read property 'prototype' of undefined”。如果我为此删除部分: app.use((req, res, next) => res.header('Access-Control-Allow-Origin', '*'); next(); ); ,错误消失了,我可以看到 React 页面,但是当我尝试单击按钮时,CORS 错误仍然存在。 您的 CORS 正常。请注释掉你所有的处理代码(我猜是推荐算法),请只运行 GET 而不带任何参数。如果您能够在 Postman 和 React 中不带任何参数运行 GET,那么请尝试向 GET 添加参数。如果它会工作,请添加推荐算法。一次解决一个问题。更容易前进。如果您对 Django 和 ML 感兴趣,可以查看我的教程 deploymachinelearning.com。我也在做 Django+React 教程saasitive.com 如果你修好了请告诉我。 您好!谢谢!我已经完成了您所说的注释算法代码并仅返回 User_ID,它确实在 Postman 和浏览器中工作,但在 React 中不起作用,因为它仍然在说“TypeError:无法读取未定义的属性'原型'”。但是,当我将此代码“user = request.query_params.get("ID")”放入views.py 以获取User_ID 值时,它不会在Postman 中返回任何内容。以上是关于GET API 在浏览器中显示 KeyError,但在 Postman 中工作的主要内容,如果未能解决你的问题,请参考以下文章
KeyError: 'commentCount' 在 Python 中使用 Youtube API