【问题标题】:Passing dynamically created json url to ajax and display to html page将动态创建的 json url 传递给 ajax 并显示到 html 页面
【发布时间】:2018-11-30 13:29:27
【问题描述】:

我目前正在开发一个系统,其中用户名和密码的登录检查由 python 函数检查。如果登录详细信息正确,它将被重定向到个人资料页面(我将其命名为仪表板)。我的问题是,如果我的 dahsboard/profile 路由是 POST 并且还具有正确的登录详细信息,则它会重新发送一个 json。我希望这个 json 数据显示在 html 文件中。我设法做到了,但我在我的 jinja 模板中使用了变量。虽然我已经实现了我的目标(在 html 页面中显示凭据),但我希望它由 ajax 处理。我该如何做到这一点?

以下是我目前尝试过的代码(将数据传递给 jinja 变量)

@app.route('/dashboard', methods=['GET', 'POST'])
def dashboard():
    if request.method == 'GET':
        #get the username passed along with the redirect
        data1= getdatafromdb('getdata1',(request.args.get('uname'),))[0][0]
        data2= getdatafromdb('getdata2',(code,))[0]

        if 'Error' in str(data2):
            return jsonify({'status': 'error', 'message': data2[0][0]})



        return render_template('dashboard.html', firstname=data2[1],
                               middleinitial=data2[2],
                               lastname=data2[3],
                               contact=data2[4],
                               code=data2[5],
                               affiliation=data2[6],
                               city=data2[7])
    elif request.method == 'POST':
        return True
    return render_template('dashboard.html')

【问题讨论】:

  • 我不明白你在这里做什么。为什么你的代码有时会渲染模板,有时会返回 JSON?
  • 我正在使用一个 python 函数,该函数旨在调用 postgres 中的存储函数。我的 python 函数也会对所有结果进行 jsonify,因为我要通过 json 与 ajax 交谈。 @丹尼尔罗斯曼
  • 但这并不能解释为什么有时会渲染模板。
  • ...它的格式(我认为)让您感到困惑。返回 jsonified 对象的代码检查 data2 是否有错误。如果是这样,它会以 jsonified 格式返回错误。但如果它没有错误,它会返回一个 render_template 以及数据(名字、中间名等),这段代码在我的另一个项目上工作。但它只是一个从 json url 获取数据的 android 应用程序。这次,我在 web 应用程序上,但我并不擅长它。

标签: python json ajax flask jinja2


【解决方案1】:

目前,您似乎正在 /dashboard 路由中运行验证过程,如果您希望在验证用户凭据后将用户重定向到该页面,则这是不正确的。相反,您需要使用ajax 创建单独的登录方法。首先,从/ (home) 路由中,使用ajax 渲染包含input 框的模板:

home.html:

<html>
 <body>
   <input type='text' name='username' id='username'>
   <div class='username_failed'></div>
   <input type='password' name='password' id='password'>
   <div class='password_failed'></div>
   <button type='button' class='login'>Login</button>
 </body>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

 <script>
  $(document).ready(function() {
   $('.login').click(function() {
    var username = $('#username').val();
    var password = $('#password').val();
    $.ajax({
      url: "/login",
      type: "get",
      data: {username: username, password:password},
      success: function(response) {
        if (!response.status){
           $('.'+response.issue+'_failed').html('<p>'+response.message+'</p>')
        }
        else{
           window.location.replace('/dashboard'); //redirect to dashboard
        }
      },
      error: function(xhr) {
      //Do Something to handle error
    }
   });
  });
 });
  </script>
</html>

然后,登录路由将从ajax 中的home.html 动态验证输入。以前,您需要创建一个函数来验证用户名和密码。一种可能是先检查它们是否为空,然后查询数据库:

import typing
def check_if_valid(username:str, password:str) -> typing.Dict[str, typing.Any]:
   if not username or not password:
     return {'status':False, 'issue':'username' if not username else 'password', 'message':f'{[username, password][username]} cannot be empty'}
   _username = check_valid_username_from_db(username) 
   _password = check_valid_password_from_db(username, password)
   if not _username:
     return {'status':False, 'issue':'username', 'message':'Invalid username'}
   if not _password:
     return {'status':False, 'issue':'password', 'message':'Invalid username or password'}
   return {'status':True}

@app.route('/login')
def login():
  username = flask.requests.args.get('username')
  password = flask.requests.args.get('password')
  _r = check_if_valid(username, password)
  if _r.status:
    data2= getdatafromdb('getdata2',(code,))[0]
    for i, a in enumerate(['firstname', 'middleinitial', 'lastname', 'contact', 'code', 'affiliation', 'city']):
      flask.session[a] = data2[i]
  flask.session['user_validated'] = _r.status
  return flask.jsonify(_r)

现在,如果用户成功验证,您的所有用户数据都将作为会话的一部分存储。现在,您可以创建仪表板页面,首先使用仪表板的 html:

dashboard.html:

<html>
 <body>
   <h1>Welcome, {{firstname}}</h1>
   <h4>Your data:</h4>
   {%for d in data%}
     <span>{{d.title}}: {{d.value}}</span>
   {%endfor%}
 </body>
</html>

然后,使用用户验证器创建仪表板路由:

def isloggedin(f):
  def wrapper(*args):
    if not flask.session['user_validated']:
      return '<p>Not logged in</p>'
    return f(*args)
  return wrapper

@app.route('/dashboard', methods=['GET'])
@isloggedin
def dashboard():
  from collections import namedtuple
  headers = ['firstname', 'middleinitial', 'lastname', 'contact', 'code', 'affiliation', 'city']
  data = namedtuple('data', ['title', 'value'])
  return flask.render_template('dashboard.html', firstname = flask.session['firstname'], data = [data(a, flask.session[a]) for a in headers[1:]])

最后,将所有路径与 home route 链接在一起:

@app.route('/', methods=['GET'])
def home():
  return flask.render_template('home.html')

【讨论】:

    猜你喜欢
    • 2017-07-24
    • 2018-01-14
    • 2018-09-05
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多