Как реализовать поле логической формы во Flask? - PullRequest
0 голосов
/ 18 сентября 2018

Я (в основном) следовал превосходному учебнику Пера Вагнера Нильсена, но затем попытался (и не смог) добавить логическое поле в форму. Кажется, что для каждого пользователя, созданного с помощью формы «Регистрация», булево значение установлено в «Истина», хотя по умолчанию установлено значение «Ложь», а при отправке формы флажок снят. Я проверяю это с помощью строки в контроллере входа в систему if user.is_admin(), и контроллер возвращает user is admin. Я показываю весь код, потому что я действительно не вижу, где лежит моя ошибка - извините, если это слишком много. Любая помощь с благодарностью.

app.py

from flask import Flask, reque,st, render_template, redirect, url_for, flash, g
from forms import SignupForm, LoginForm
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, login_user, login_required, logout_user
from flask.ext.login import current_user

app = Flask(__name__)
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)

login_manager = LoginManager()
login_manager.init_app(app)

######################################################################
# Models
######################################################################
class User(db.Model):
    email = db.Column(db.String(80), primary_key=True, unique=True)
    password = db.Column(db.String(80))
    is_admin = db.Column(db.Boolean, default=False)

    def __init__(self, email, password, is_admin):
        self.email = email
        self.password = password
        self.is_admin = is_admin

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return str(self.email)

    def is_admin(self):
        if self.is_admin:
            return True
        else:
            return False

    def __repr__(self):
        return '<User %r>' % self.email

######################################################################
@login_manager.user_loader
def load_user(email):
    return User.query.filter_by(email = email).first()

@app.before_request
def before_request():
    g.user = current_user

######################################################################
# Routes
######################################################################
@app.route('/')
def index():
    return "Welcome to Flask"

@app.route('/signup', methods=['GET', 'POST'])
def signup():
    form = SignupForm()
    if request.method == 'GET':
        return render_template('signup.html', form = form)
    elif request.method == 'POST':
        if form.validate_on_submit():
            if User.query.filter_by(email=form.email.data).first():
                return "Email address already exists"
            else:
                newuser = User(form.email.data, form.password.data, form.is_admin.data)
                db.session.add(newuser)
                db.session.commit()
                return "User created"
        else:
            #return "Form didn't validate"
            return render_template('signup.html', form=form)

@app.route('/login', methods=['GET','POST'])
def login():
    form = LoginForm()
    if request.method == 'GET':
        return render_template('login.html', form=form)
    elif request.method == 'POST':
        if form.validate_on_submit():
            user=User.query.filter_by(email=form.email.data).first()
            if user:
                if user.password == form.password.data:
                    login_user(user)
                    #return "User logged in"
                    if user.is_admin():
                        return "user is admin"
                    else:
                        return "user is not admin"
                else:
                    return "Wrong password"
            else:
                return "user doesn't exist"
    else:
        return "form not validated"

@app.route("/logout")
@login_required
def logout():
    logout_user()
    return "Logged out"

@app.route('/protected')
@login_required
def protected():
    return "protected area, user: " + current_user.email + ", " + str(g.user.is_admin)
######################################################################

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, validators, BooleanField
from wtforms.validators import Email, DataRequired


class SignupForm(FlaskForm):
    email = StringField('Email',
                [DataRequired(),Email()])
    password = PasswordField(
                'Password',
                [DataRequired()])
    is_admin = BooleanField('Is an Admin')
    submit = SubmitField("Sign In")


class LoginForm(FlaskForm):
    email = StringField('Email',
                [DataRequired(),Email()])
    password = PasswordField(
                'Password',
                [DataRequired()])
    submit = SubmitField("Sign In")

шаблоны / signup.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Access</title>
</head>
<body>
    <h1>Sign-up</h1>
    <form method="POST" action="/signup">
        {{ form.hidden_tag() }}
        {{ form.email.label }} {{ form.email(size=20) }}<br>
        {{ form.password.label }} {{ form.password(size=20) }}<br>
        {{ form.is_admin.label }} {{ form.is_admin() }}<br>

        <input type="submit" value="Signup">
    </form>

<h1>Form Errors</h1>
{{ form.errors }}
</body>
</html>

шаблоны / login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form method="POST" action="/login">
        {{ form.hidden_tag() }}
        {{ form.email.label }} {{ form.email(size=20) }}
        {{ form.password.label }} {{ form.password(size=20) }}
        <input type="submit" value="login">
    </form>
</body>
</html>

1 Ответ

0 голосов
/ 18 сентября 2018

Проблема заключается в том, что в вашем классе модели есть столбец is_admin и функция с именем is_admin().В Python, если вы хотите использовать одно и то же имя для переменной класса и метода класса, вам лучше знать, что вы делаете (но не).

Чтобы избежать этого, простовы можете переименовать вашу функцию от is_admin() до is_administrator().

Но если вы подумаете об этом, вычисление непосредственно поля в вашей функции представления без необходимости объявления метода класса будет еще проще:

if user.is_admin:
    return "user is admin"
else:
    return "user is not admin"

Я бы также порекомендовал взглянуть на Выражение SQL и сопоставленные атрибуты , чтобы лучше понять, что вы делаете со всеми этими методами класса в вашей модели.

...