【问题标题】:Flask creating a unique profile page for each userFlask 为每个用户创建一个独特的个人资料页面
【发布时间】:2013-11-28 08:41:25
【问题描述】:

我想使用 Flask 在我的网站上为每个注册用户创建一个独特的个人资料页面。目前,我的个人资料页面代码是这样的:

@app.route('/profile/')
def profile():

if 'email' not in session:
    return redirect(url_for('signin'))

user = User.query.filter_by(email = session['email']).first()

if user is None:
    return redirect(url_for('signin'))
else:
    return render_template('profile.html')

但是,当我尝试改变时

@app.route('/profile/<lastname>')
def profile(lastname):

我收到 werkzeug.routing.BuildError。我的问题是,我是否在为每个用户创建一个独特的个人资料页面的正确轨道上,如果是这样,我怎样才能将变量添加到我的 url,这样我就不会收到 BuildError?谢谢您的帮助。

这是完整的 routes.py 代码:

from intro_to_flask import app
from flask import Flask, render_template, request, flash, session, redirect, url_for
from forms import ContactForm, SignupForm, SigninForm
from flask.ext.mail import Message, Mail
from models import db, User

mail = Mail()

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/contact', methods=['GET', 'POST'])
def contact():
    form = ContactForm()

    if request.method == 'POST':
        if form.validate_on_submit() == False:
            return render_template('contact.html', form=form)
        else:        
            name = request.form['name']
            subject = request.form['subject']
            senderEmail = request.form['email']
            message = request.form['message']
            msg = Message(subject, sender = senderEmail, recipients=    ['myemailaddress@gmail.com'])
        msg.body = message + "\n\n" + name + " (" + senderEmail + ")"
        mail.send(msg)
        return render_template('contact.html', success=True)

elif request.method == 'GET':
    return render_template('contact.html', form=form)

@app.route('/signup', methods = ['GET', 'POST'])
def signup():
    form = SignupForm()    

    if 'email' in session:
        return redirect(url_for('profile'))

    if request.method == 'POST':
        if form.validate() == False:
            return render_template('signup.html', form = form)
        else:
            newuser = User(form.firstname.data, form.lastname.data, form.email.data,  form.password.data)
            db.session.add(newuser)
            db.session.commit()

            session['email'] = newuser.email

            return redirect(url_for('profile'))

    elif request.method == 'GET':
        return render_template('signup.html', form = form)

@app.route('/profile/')
def profile():

    if 'email' not in session:
        return redirect(url_for('signin'))

    user = User.query.filter_by(email = session['email']).first()

    if user is None:
        return redirect(url_for('signin'))
    else:
        return render_template('profile.html')

@app.route('/signin', methods=['GET', 'POST'])
def signin():
    form = SigninForm()    

    if 'email' in session:
        return redirect(url_for('profile'))

    if request.method == 'POST':
        if form.validate() == False:
            return render_template('signin.html', form=form)
        else:
            session['email'] = form.email.data
            return redirect(url_for('profile'))

    elif request.method == 'GET':
        return render_template('signin.html', form = form) 

@app.route('/signout')
def signout():

    if 'email' not in session:
        return redirect(url_for('signin'))

    session.pop('email', None)
    return redirect(url_for('home'))

我相信 BuildError 来自我调用 url_for('profile') 但我的配置文件函数将 lastname 作为参数并且它没有反映在我的 url_for 命令中。我只是不确定应该在我的 url_for 方法中包含什么参数。

这是我的 models.py 的代码:

from flask.ext.sqlalchemy import SQLAlchemy
from werkzeug import generate_password_hash, check_password_hash

db = SQLAlchemy()

class User(db.Model):
    __tablename__ = 'users'
    uid = db.Column(db.Integer, primary_key = True)
    firstname = db.Column(db.String(100))
    lastname = db.Column(db.String(100))
    email = db.Column(db.String(120), unique = True)
    pwdhash = db.Column(db.String(54))    

    def __init__(self, firstname, lastname, email, password):
        self.firstname = firstname.title()
        self.lastname = lastname.title()
        self.email = email.lower()
        self.set_password(password)

    def set_password(self, password):
        self.pwdhash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.pwdhash, password)

【问题讨论】:

  • 问题不在您显示的代码中,您必须在忘记添加lastname 参数的地方调用url_for()

标签: python flask


【解决方案1】:

这里有 2 个问题:

  1. 身份验证
  2. 网址路由

认证

你做错了。为什么在会话中存储电子邮件地址并在函数中每次都访问它? 我建议您使用名为 Flask-Login 的烧瓶扩展。 它为您处理所有事情,并为您的登录用户公开一个current_user 代理。

如需参考实现,请按照官方网站上的教程或查看this Flask mini framework

网址路由

你定义了:

@app.route('/profile/<lastname>')
def profile(lastname):

所以lastname 是一个强制参数。你需要这样调用它:

url_for('.profile', lastname='foo')

【讨论】:

  • 感谢您的回复。当我将代码更改为 url_for('.profile', lastname='foo') 时,我的 url 变为:localhost:5000/profile/foo。我想要用户的实际姓氏,而不是 foo 在 URL 中。
  • @user3016362 是的,您需要用您的姓氏变量替换foo(它是一个占位符)。像user.last_name 这样的东西。这真的取决于user 对象。
【解决方案2】:

您需要更改配置文件路由的装饰器并使其动态化:从@app.route('/profile/')@app.route('/profile/&lt;lastname&gt;') 然后从数据库db,特别是从User 表中获取姓氏。最后返回的配置文件页面还应该包含lastname 变量。 个人资料页面的完整代码如下所示。

from intro_to_flask import app
from flask import Flask, render_template, request, flash, session, redirect, url_for
from forms import ContactForm, SignupForm, SigninForm
from flask.ext.mail import Message, Mail
from models import db, User

mail = Mail()


# The rest of your routes



@app.route('/profile/<lastname>')
def profile(lastname):
    profile = User.query.filter_by(lastname=lastname).first()
    if profile is None:
        return redirect(url_for('signin'))
    else:
        return render_template('profile.html', lastname=lastname)

【讨论】:

    猜你喜欢
    • 2018-12-09
    • 2012-06-30
    • 1970-01-01
    • 2015-09-24
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多