最新消息:20181230 VPS服务器已从Linode换到腾讯云香港,主题仍用朋友推荐的大前端D8

[已搞懂]Flask的Jinja中在url_for传递参数时候无法传递对象

Flask crifan 1159浏览 0评论

在Flask的Jinja的模版的html中,以及Flask的views.py中的路由中

跳转到对应的页面的时候,传递的参数,无法保持原先的对象

具体现象是:

代码:

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/views.py

@app.route(“/”)
def index():
    requestArgs = request.args
    app.logger.debug(‘requestArgs=%s’, requestArgs)
    # curUser = request.args.get(“curUser”, None)
    curUser = request.args.get(“curUser”, User(openid=””))
    app.logger.debug(‘curUser=%s’, curUser)
    app.logger.debug(‘type(curUser)=%s’, type(curUser))
    #if curUser is None :
    if not curUser.openid:
        needRedirect = False
        paraCode = request.args.get(‘code’, ”)
        app.logger.debug(‘paraCode=%s’, paraCode)
        if not paraCode:
            needRedirect = True
        paraState = request.args.get(‘state’, ”)
        app.logger.debug(‘paraState=%s’, paraState)
        # if not paraState :
        #     needRedirect = True
        app.logger.debug(‘needRedirect=%s’, needRedirect)
        if needRedirect:
            # 1. redirect url
            redirect_uri = “http://hd.webonn.com”
            authorize_url = wechat.generate_oauth2_authorize_url(redirect_uri)
            app.logger.debug(‘redirect_uri=%s, authorize_url=%s’, redirect_uri, authorize_url)
            return redirect(authorize_url)
        else:
            # 2. get access token
            respAccessToken = wechat.get_oauth2_access_token(paraCode)
            app.logger.debug(‘respAccessToken=%s’, respAccessToken)
            # respAccessToken={u’access_token’: u’5Lnjm56ox1djVEFEIAdvp4HdcHVO1WsEWCDXVIS0zLZc3veMB4KXLMu843h_MpLJ6xLjlHGeclhhhSsErowWCeFMBMC3CbWX4zDezvu_D7M’, u’openid’: u’oswxxxxxxxxxxxxxxxxxxxxxxVVY’, u’expires_in’: 7200, u’refresh_token’: u’QE-prEWTMHrDBqZGcJLYOg5fNqvpVL6qrp2YekXlyWq2agtwsGhO5IIxujpIBwXzUMy80n7d9xiWFZEwrNt10ilFpRkTbwP4cBzQ2df7eUw’, u’scope’: u’snsapi_userinfo’}
            respAccessTokenStr = jsonToStr(respAccessToken)
            app.logger.debug(‘respAccessTokenStr=%s’, respAccessTokenStr)
            # respAccessTokenStr = {
            #     “access_token”: “K8EMRg7DTYnElLOgLix0yVIKeSg85KWmChnGK4PZ8T5N2EiHevQZEm6hyMBPfkOh5Hl3r0H_koLFmHuMFuGOXoyLMn-A7IT0ztqPKvi6TIY”,
            #     “openid”: “oswxxxxxxxxxxxxxxxxxxxxxxVVY”,
            #     “expires_in”: 7200,
            #     “refresh_token”: “wWfqaQyxbAK4WUKwmPeTuSQ7_Nlnxz35xAZ5fu6ZlQseR526zKyemwA7YozbUmbGYSETIpGCi0T-HXMhgKXKVvi5Kon2_4_uWAwhNcxCRBI”,
            #     “scope”: “snsapi_userinfo”
            # }
            oauth2Access_token = respAccessToken[‘access_token’]
            oauth2Openid = respAccessToken[‘openid’]
            app.logger.debug(‘oauth2Access_token=%s, oauth2Openid=%s’, oauth2Access_token, oauth2Openid)
            respUserInfoDict = wechat.get_oauth2_userinfo(oauth2Access_token, oauth2Openid)
            app.logger.debug(‘type(respUserInfoDict)=%s, respUserInfoDict=%s’, type(respUserInfoDict), respUserInfoDict)
            # type(respUserInfoDict) = < type ‘dict’ >, respUserInfoDict = {u’province’: u’\xe6\xb1\x9f\xe8\x8b\x8f’,
            #                               u’openid’: u’oswxxxxxxxxxxxxxxxxxxxxxxVVY’,
            #                               u’headimgurl’: u’http://wx.qlogo.cn/mmopen/ajNVdqHZLLDYtIJicNl7MjwZK5c1lxAJZ253c9v3JzDib7GeE5OFrWiaRqsK1ruW1HmGaziaYETV5vQhIIbic6wHKFQ/0′,
            #                               u’language’: u’zh_CN’, u’city’: u’\xe8\x8b\x8f\xe5\xb7\x9e’,
            #                               u’country’: u’\xe4\xb8\xad\xe5\x9b\xbd’, u’sex’: 1, u’privilege’: [],
            #                               u’nickname’: u’\xe7\xa4\xbc\xe8\xb2\x8c’}
            province = respUserInfoDict[‘province’]
            city = respUserInfoDict[‘city’]
            country = respUserInfoDict[‘country’]
            nickname = respUserInfoDict[‘nickname’]
            app.logger.debug(‘province=%s, city=%s, country=%s, nickname=%s’, province, city, country, nickname)
            app.logger.debug(‘type(province)=%s’, type(province))
            openid = respUserInfoDict[‘openid’]
            currentUsers = User.query.all()
            app.logger.debug(‘currentUsers=%s’, currentUsers)
            currentUsersCount = len(currentUsers)
            app.logger.debug(‘currentUsersCount=%s’, currentUsersCount)
            existedUser = User.query.filter_by(openid = openid).first()
            callbackOkStr = “”
            if existedUser :
                # has exsited this user
                #callbackOkStr = u’已存在此用户 existedUser=%r’ % (existedUser)
                callbackOkStr = u’已存在此用户 openid=%s, nickname=%s’ % (openid, nickname)
                app.logger.debug(“type(existedUser)=%s”, type(existedUser))
                curUser = existedUser
                app.logger.debug(“type(curUser)=%s”, type(curUser))
            else:
                #download avatar image
                avatarUrl = respUserInfoDict[‘headimgurl’]
                app.logger.debug(“avatarUrl=%s”, avatarUrl)
                avatarReq = requests.get(avatarUrl)
                app.logger.debug(“avatarReq=%s”, avatarReq)
                staticFolder = app.static_folder
                app.logger.debug(“staticFolder=%s”, staticFolder)
                avatartName = openid + “.png”
                app.logger.debug(“avatartName=%s”, avatartName)
                avatarStaticPath = os.path.join(“img/avatar”, avatartName)
                app.logger.debug(“avatarStaticPath=%s”, avatarStaticPath)
                avatarFullPath = os.path.join(staticFolder, avatarStaticPath)
                app.logger.debug(“avatarFullPath=%s”, avatarFullPath)
                with open(avatarFullPath, ‘wb’) as f:
                    f.write(avatarReq.content)
                    f.close()
                    app.logger.debug(“downloaded avatar=%s ok”, avatarUrl)
                # new user, need save
                respUserObj = User( openid = respUserInfoDict[‘openid’],
                                    province = respUserInfoDict[‘province’],
                                    avatar_url = respUserInfoDict[‘headimgurl’],
                                    avatar_static_path = avatarStaticPath,
                                    language = respUserInfoDict[‘language’],
                                    city = respUserInfoDict[‘city’],
                                    country = respUserInfoDict[‘country’],
                                    sex = respUserInfoDict[‘sex’],
                                    nickname = respUserInfoDict[‘nickname’])
                app.logger.debug(‘respUserObj=%s’, respUserObj)
                db.session.add(respUserObj)
db.session.commit()
                app.logger.debug(‘added respUserObj=%s’, respUserObj)
                app.logger.debug(“type(respUserObj)=%s”, type(respUserObj))
                curUser = respUserObj
                app.logger.debug(“type(curUser)=%s”, type(curUser))
                respUserInfoStr = jsonToStr(respUserInfoDict)
                app.logger.debug(‘type(respUserInfoStr)=%s, respUserInfoStr=%s’, type(respUserInfoStr), respUserInfoStr)
                callbackOkStr = u”已成功添加用户: respUserInfoStr=%s” % (respUserInfoStr)
            app.logger.debug(“callbackOkStr=%s”, callbackOkStr)
    app.logger.debug(“curUser=%s”, curUser)
    app.logger.debug(“type(curUser)=%s”, type(curUser))
    currentUsers = User.query.all()
    app.logger.debug(‘currentUsers=%s’, currentUsers)
    currentUsersCount = len(currentUsers)
    app.logger.debug(‘currentUsersCount=%s’, currentUsersCount)
    todayEventList = Event.query.filter_by(user_openid = curUser.openid).all()
    app.logger.debug(“todayEventList=%s”, todayEventList)
    # return make_response(callbackOkStr)
    return render_template(‘index.html’, curUser= curUser, todayEventList = todayEventList)
@app.route(‘/creat_event’, methods=[‘GET’, ‘POST’])
def creat_event():
    requestMethod = request.method
    app.logger.debug(‘requestMethod=%s’, requestMethod)
    requestArgs = request.args
    app.logger.debug(‘requestArgs=%s’, requestArgs)
    #curUser = request.args.get(“curUser”, None)
    curUser = request.args.get(“curUser”, User(openid=””))
    app.logger.debug(‘curUser=%s’, curUser)
    app.logger.debug(‘type(curUser)=%s’, type(curUser))
    if request.method == ‘POST’:
        requestForm = request.form
        app.logger.debug(“requestForm=%s”, requestForm)
        title               = requestForm.get(“title”, “”)
        start_date          = requestForm.get(“start_date”, “”)
        end_date            = requestForm.get(“end_date”, “”)
        location            = requestForm.get(“location”, “”)
        max_user_num        = requestForm.get(“max_user_num”, “”)
        is_public           = requestForm.get(“is_public”, “”)
        description         = requestForm.get(“description”, “”)
        notification_time   = requestForm.get(“notification_time”, “”)
        app.logger.debug(“title=%s, start_date=%s, end_date=%s, location=%s, max_user_num=%s, is_public=%s, description=%s, notification_time=%s”,
                         title, start_date, end_date, location, max_user_num, is_public, description, notification_time)
        # 2016/8/26 10:09
        # start_date = datetime.strptime(start_date, “%y/%m/%d %H:%M”)
        return redirect(url_for(‘index’, curUser = curUser))
    else:
        return render_template(“creatEvent.html”, curUser = curUser)

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/templates/creatEvent.html

<form action=”{{ url_for(“creat_event”, curUser=curUser) }}” method=”POST”>

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/templates/index.html

<a href=”{{ url_for(‘creat_event’, curUser = curUser) }}” class=”link icon-only” class=”external”>

对应的log是:

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:317]:
curUser=<User nickname=u’\u793c\u8c8c’ openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY avatar_static_path=img/avatar/oswjmv4X0cCXcfkIwjoDfCkeTVVY.png>

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:318]:
type(curUser)=<type ‘unicode’>

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:322]:
requestForm=ImmutableMultiDict([(‘notification_time’, u’\u4e0d\u63d0\u9192′), (‘description’, u”), (‘end_date’, u’2016/8/26 10:46′), (‘title’, u’\u96c6\u4f53′), (‘location’, u”), (‘start_date’, u’2016/8/26 10:46′), (‘max_user_num’, u”)])

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:333]:
title=集体, start_date=2016/8/26 10:46, end_date=2016/8/26 10:46, location=, max_user_num=, is_public=, description=, notification_time=不提醒

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:168]:
requestArgs=ImmutableMultiDict([(‘curUser’, u”<User nickname=u’\\u793c\\u8c8c’ openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY avatar_static_path=img/avatar/oswjmv4X0cCXcfkIwjoDfCkeTVVY.png>”)])

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:172]:
curUser=<User nickname=u’\u793c\u8c8c’ openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY avatar_static_path=img/avatar/oswjmv4X0cCXcfkIwjoDfCkeTVVY.png>

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:173]:
type(curUser)=<type ‘unicode’>

<div–<——————————————————————————

[2016-08-26 10:46:43 +0000] [32292] [ERROR] Error handling request /?curUser=%3CUser+nickname%3Du%27%5Cu793c%5Cu8c8c%27+openid%3Doswjmv4X0cCXcfkIwjoDfCkeTVVY+avatar_static_path%3Dimg%2Favatar%2Foswjmv4X0cCXcfkIwjoDfCkeTVVY.png%3E
Traceback (most recent call last):
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/gunicorn/workers/sync.py”, line 135, in handle
    self.handle_request(listener, req, client, addr)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/gunicorn/workers/sync.py”, line 176, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 2000, in __call__
    return self.wsgi_app(environ, start_response)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1991, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1567, in handle_exception
    reraise(exc_type, exc_value, tb)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1988, in wsgi_app
    response = self.full_dispatch_request()
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1641, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1544, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1639, in full_dispatch_request
    rv = self.dispatch_request()
  File “/root/Envs/SIPEvents/lib/python2.7/site-packages/flask/app.py”, line 1625, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File “/usr/share/nginx/html/SIPEvents/sipevents/views.py”, line 176, in index
    if not curUser.openid:
AttributeError: ‘unicode’ object has no attribute ‘openid’

在之前,views.py中的,是User这个对象

但是传递到html中,再GET或POST会到views.py中的路由中,就变成了对应的unicode类型了。

类似的,之前用:

curUser = request.args.get(“curUser”, “”)

以为是默认值,导致变量是unicode

去改为None:

curUser = request.args.get(“curUser”, None)

结果还是

最后改为现在的:

curUser = request.args.get(“curUser”, User(openid=””))

结果还是unicode类型。。。

-》

然后自己看了半天,有点明白了:

此处的,通过Html跳转到路由中的,不论是GET还是POST,都只能是:

传递过来对应的字符串

-》所以此处,接收到的是对象格式化后的字符串:

DEBUG in views [/usr/share/nginx/html/SIPEvents/sipevents/views.py:317]:
curUser=<User nickname=u’\u793c\u8c8c’ openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY avatar_static_path=img/avatar/oswjmv4X0cCXcfkIwjoDfCkeTVVY.png>

并非对象本身。

Jinjia url_for pass object

python – How can I “redirect” to another URL and pass a list object using Flask – Stack Overflow

python – Getting a request parameter in Jinja2 – Stack Overflow

Python, Flask – Passing Arguments Into redirect(url_for()) – Stack Overflow

Jinja call flask router pass object

python – How can I pass data from Flask to JavaScript in a template? – Stack Overflow

[总结]

换言之:

Html到路由,不论GET还是POST,都只能传递字符串级别的内容,而无法传递整个对象

-》除非对象进行编码和解码。。。

->不过,反过来:

在views.py中的路由中,用

render_template的时候,是可以传递整个对象到Html中的

然后jinjia中用对应for someList去生成对应的html代码。

-》稍微高级点的办法可以是:

把对象转换为json,从html中的url_for时,传递到flask中的路由中

路由中通过request.get的得到json后,可以解析出对应的字典变量-》可以获得更多的信息,但是无法传递完整的object对象变量

转载请注明:在路上 » [已搞懂]Flask的Jinja中在url_for传递参数时候无法传递对象

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
59 queries in 0.244 seconds, using 9.45MB memory