0
0 комментариев

Проблема моя возникает в том, что я хочу сделать панель как при помощи flask-admin, но для юзера который входит в свой личный кабинет и там хотя бы отображалась панель с ссылками формами заполнения. Чтобы юзер когда заполнял их то они отправлялись админу в базу данных! Такое возможно? Можете что то посоветовать?

На данный момент код вот такой:

import os
 
from flask import Flask, render_template, url_for, redirect, request, session, flash, abort
from flask_sqlalchemy import SQLAlchemy
from flask_admin import helpers, expose
from flask_admin import helpers as admin_helpers
import flask_admin as admin
import flask_login as login
 
from datetime import datetime
 
from flask_admin.contrib import sqla
 
from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin, login_user, \
    login_required, logout_user, current_user
 
from wtforms import form, StringField, PasswordField, BooleanField, validators, fields
 
from flask_security.utils import encrypt_password
 
from werkzeug.security import generate_password_hash, check_password_hash
 
app = Flask(__name__)
 
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SECRET_KEY'] = 'thisissecret'
 
db = SQLAlchemy(app)
 
# Define models
roles_users = db.Table(
 
    'roles_users',
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)
 
 
class Role(RoleMixin, db.Model):
 
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))
 
    def __str__(self):
        return self.name
 
 
class User(UserMixin, db.Model):
 
    id = db.Column(db.Integer, primary_key=True)
    login = db.Column(db.String(255))
    email = db.Column(db.String(50), unique=True)
    password = db.Column(db.String(100))
    active = db.Column(db.Boolean())
    registered_on = db.Column('registered_on', db.DateTime)
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))
 
 
    # Flask-Login integration
    def is_authenticated(self):
        return True
 
 
    def is_active(self):
        return True
 
 
    def is_anonymous(self):
        return False
 
 
    def get_id(self):
        return self.id
 
 
# Required for administrative interface
    def __unicode__(self):
 
        return self.login
 
 
    def __repr__(self):
 
        return '<User %r>' % self.login
 
 
    def __str__(self):
 
        return self.email
        # Setup Flask-Security
 
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
 
security = Security(app, user_datastore)
 
 
# Define login and registration forms (for flask-login)
class LoginForm(form.Form):
 
    user_message = 'Mailing address should be no more than 60 characters'
    user_required = 'Please enter your login.'
    pass_message = 'Password should be no more than 50 characters'
    pass_required = 'Please enter your password.'
 
    login = fields.StringField('Username', validators=[validators.Length(message=user_message, max=60),
                                                    validators.required(user_required)])
    password = fields.PasswordField('Password', validators=[validators.Length(message=pass_message, max=50),
                                                            validators.required(pass_required)])
 
    def get_user(self):
        return db.session.query(User).filter_by(login=self.login.data).first()
 
    def validate_login(self, field):
        user = self.get_user()
 
        if user is None:
            raise validators.ValidationError('Invalid user')
 
        # we're comparing the plaintext pw with the the hash from the db
        if not check_password_hash(user.password, self.password.data):
            # to compare plain text passwords use
            # if user.password != self.password.data:
            raise validators.ValidationError('Invalid password')
 
 
class RegistrationForm(form.Form):
 
    username_message = 'The name must be at least 4 letters and no more than 25 characters'
    username_required = 'Please enter your login.'
    email_address_message = 'Mailing address should be no more than 60 characters'
    email_address_required = 'Please enter your email address.'
    password_message = 'Passwords must match'
 
    login = fields.StringField('Username', validators=[validators.Length(message=username_message, min=4, max=25),
                                                       validators.required(username_required)])
    email = fields.StringField('Email', validators=[validators.Length(message=email_address_message, max=60),
                                                            validators.required(email_address_required)])
    password = fields.PasswordField('Password', validators=[validators.required(password_message),
                                                validators.EqualTo('confirm', message='Passwords must match')])
    confirm = fields.PasswordField('Repeat Password')
 
    def validate_login(self, field):
        if db.session.query(User).filter_by(login=self.login.data).count() > 0:
            raise validators.ValidationError('Duplicate username')
        if db.session.query(User).filter_by(email=self.email.data).count() > 0:
            raise validators.ValidationError('Duplicate email')
 
 
 
# Initialize flask-login
def init_login():
 
    login_manager = login.LoginManager()
    login_manager.init_app(app)
 
    # Create user loader function
    @login_manager.user_loader
    def load_user(user_id):
 
        return db.session.query(User).get(user_id)
 
 
# Create customized model view class
class MyModelView(sqla.ModelView):
 
    def is_accessible(self):
        if not current_user.is_active or not current_user.is_authenticated:
            return False
 
        if current_user.has_role('superuser'):
            return True
 
        return False
 
    def _handle_view(self, name, **kwargs):
        """
        Override builtin _handle_view in order to redirect users when a view is not accessible.
        """
        if not self.is_accessible():
            if current_user.is_authenticated:
                # permission denied
                abort(403)
            else:
                # login
                return redirect(url_for('admin.login_view', next=request.url))
 
 
# Create customized index view class that handles login & registration
class MyAdminIndexView(admin.AdminIndexView):
 
    @expose('/')
    def index(self):
        if not login.current_user.is_authenticated:
            return redirect(url_for('.login_view'))
        return super(MyAdminIndexView, self).index()
 
    @expose('/login/', methods=['GET', 'POST'])
    def login_view(self):
        # handle user login
        form = LoginForm(request.form)
        if helpers.validate_form_on_submit(form):
            user = form.get_user()
            login.login_user(user)
 
        if login.current_user.is_authenticated:
            return redirect(url_for('.index'))
        link = '<p>Don\'t have an account? <a href="' + url_for('.register_view') + '">Click here to register.</a></p>'
        self._template_args['form'] = form
        self._template_args['link'] = link
        return super(MyAdminIndexView, self).index()
 
    @expose('/register/', methods=['GET', 'POST'])
    def register_view(self):
        form = RegistrationForm(request.form)
        if helpers.validate_form_on_submit(form):
            user = User()
 
            form.populate_obj(user)
            # we hash the users password to avoid saving it as plaintext in the db,
            # remove to use plain text:
            user.password = generate_password_hash(form.password.data)
 
            db.session.add(user)
            db.session.commit()
 
            login.login_user(user)
            return redirect(url_for('.index'))
        link = '<p>Already have an account? <a href="' + url_for('.login_view') + '">Click here to log in.</a></p>'
        self._template_args['form'] = form
        self._template_args['link'] = link
        return super(MyAdminIndexView, self).index()
 
    @expose('/logout/')
    def logout_view(self):
        login.logout_user()
        return redirect(url_for('.index'))
 
 
# Flask views
@app.route('/')
def index():
 
    return render_template('index.html')
 
 
# Initialize flask-login
init_login()
 
# Create admin
admin = admin.Admin(app, index_view=MyAdminIndexView(), base_template='my_master.html')
 
# Add view
admin.add_view(MyModelView(User, db.session))
 
admin.add_view(MyModelView(Role, db.session))
 
 
 
 
# define a context processor for merging flask-admin's template context into the
# flask-security views.
@security.context_processor
def security_context_processor():
 
    return dict(
        admin_base_template=admin.base_template,
        admin_view=admin.index_view,
        h=admin_helpers,
        get_url=url_for
    )
 
 
def build_sample_db():
    """
    Populate a small db with some example entries.
    """
 
    db.create_all()
 
    with app.app_context():
 
        user_role = Role(name='user')
        super_user_role = Role(name='superuser')
        db.session.add(user_role)
        db.session.add(super_user_role)
        db.session.commit()
 
 
        test_user = user_datastore.create_user(
            login='Admin',
            email='admin',
            password=generate_password_hash('admin'),
            roles=[user_role, super_user_role]
        )
        db.session.add(test_user)
        db.session.commit()
 
    return
 
 
if __name__ == '__main__':
    # Build a sample db on the fly, if one does not exist yet.
    app_dir = os.path.realpath(os.path.dirname(__file__))
    database_path = os.path.join(app_dir, app.config['DATABASE_FILE'])
    if not os.path.exists(database_path):
        build_sample_db()
 
    # Start app
    app.run(debug=True)


Добавить комментарий