Advertisement
Guest User

Untitled

a guest
Mar 6th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.29 KB | None | 0 0
  1. Выбивает вот такую вот ошибку
  2.  
  3. (venv) D:projectprobeprojectflasksite>python app.py
  4. Traceback (most recent call last):
  5. File "app.py", line 263, in <module>
  6. class ImageView(sqla.ModelView):
  7. File "app.py", line 278, in ImageView
  8. 'path': form.ImageUploadField('Image',
  9. AttributeError: module 'wtforms.form' has no attribute 'ImageUploadField'
  10.  
  11. import os
  12. import os.path as op
  13. from sqlalchemy.event import listens_for
  14. from jinja2 import Markup
  15. from flask import Flask, Blueprint, render_template, url_for, redirect, request, session, flash, abort
  16. from flask_sqlalchemy import SQLAlchemy
  17. from flask_admin import helpers, expose, form
  18. from flask_admin import helpers as admin_helpers
  19. import flask_admin as admin
  20. import flask_login as login
  21. from flask_admin.contrib import sqla
  22. from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin, current_user
  23. from wtforms import form, StringField, PasswordField, BooleanField, validators, fields
  24. from werkzeug.security import generate_password_hash, check_password_hash
  25.  
  26. # Create application
  27. app = Flask(__name__, static_folder='files')
  28.  
  29. app.config['DATABASE_FILE'] = 'sample_db.sqlite'
  30. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
  31. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
  32. app.config['SECRET_KEY'] = 'thisissecret'
  33.  
  34. db = SQLAlchemy(app)
  35.  
  36. # Create directory for file fields to use
  37. file_path = op.join(op.dirname(__file__), 'static/images/menu-product')
  38. try:
  39. os.mkdir(file_path)
  40. except OSError:
  41. pass
  42.  
  43. # Define models
  44. roles_users = db.Table(
  45. 'roles_users',
  46. db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
  47. db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
  48. )
  49.  
  50.  
  51. class Role(RoleMixin, db.Model):
  52. id = db.Column(db.Integer(), primary_key=True)
  53. name = db.Column(db.String(80), unique=True)
  54. description = db.Column(db.String(255))
  55.  
  56. def __str__(self):
  57. return self.name
  58.  
  59.  
  60. # Create models
  61. class File(db.Model):
  62. id = db.Column(db.Integer, primary_key=True)
  63. name = db.Column(db.Unicode(64))
  64. path = db.Column(db.Unicode(128))
  65.  
  66. def __unicode__(self):
  67. return self.name
  68.  
  69.  
  70. class Image(db.Model):
  71. id = db.Column(db.Integer, primary_key=True)
  72. name = db.Column(db.Unicode(64))
  73. path = db.Column(db.Unicode(128))
  74.  
  75. def __unicode__(self):
  76. return self.name
  77.  
  78.  
  79. class User(UserMixin, db.Model):
  80. id = db.Column(db.Integer, primary_key=True)
  81. login = db.Column(db.String(255))
  82. email = db.Column(db.String(50), unique=True)
  83. password = db.Column(db.String(100))
  84. active = db.Column(db.Boolean())
  85. registered_on = db.Column('registered_on', db.DateTime)
  86. roles = db.relationship('Role', secondary=roles_users,
  87. backref=db.backref('users', lazy='dynamic'))
  88.  
  89. # Flask-Login integration
  90. def is_authenticated(self):
  91. return True
  92.  
  93. def is_active(self):
  94. return True
  95.  
  96. def is_anonymous(self):
  97. return False
  98.  
  99. def get_id(self):
  100. return self.id
  101.  
  102. # Required for administrative interface
  103. def __unicode__(self):
  104. return self.login
  105.  
  106. def __repr__(self):
  107. return '<User %r>' % self.login
  108.  
  109. def __str__(self):
  110. return self.email
  111. # Setup Flask-Security
  112.  
  113.  
  114. user_datastore = SQLAlchemyUserDatastore(db, User, Role)
  115. security = Security(app, user_datastore)
  116.  
  117.  
  118. # Define login and registration forms (for flask-login)
  119. class LoginForm(form.Form):
  120. user_message = 'Mailing address should be no more than 60 characters'
  121. user_required = 'Please enter your login.'
  122. pass_message = 'Password should be no more than 50 characters'
  123. pass_required = 'Please enter your password.'
  124.  
  125. login = fields.StringField('Username', validators=[validators.Length(message=user_message, max=60),
  126. validators.required(user_required)])
  127. password = fields.PasswordField('Password', validators=[validators.Length(message=pass_message, max=50),
  128. validators.required(pass_required)])
  129.  
  130. def get_user(self):
  131. return db.session.query(User).filter_by(login=self.login.data).first()
  132.  
  133. def validate_login(self, field):
  134. user = self.get_user()
  135.  
  136. if user is None:
  137. raise validators.ValidationError('Invalid user')
  138.  
  139. # we're comparing the plaintext pw with the the hash from the db
  140. if not check_password_hash(user.password, self.password.data):
  141. # to compare plain text passwords use
  142. # if user.password != self.password.data:
  143. raise validators.ValidationError('Invalid password')
  144.  
  145.  
  146. class RegistrationForm(form.Form):
  147. username_message = 'The name must be at least 4 letters and no more than 25 characters'
  148. username_required = 'Please enter your login.'
  149. email_address_message = 'Mailing address should be no more than 60 characters'
  150. email_address_required = 'Please enter your email address.'
  151. password_message = 'Passwords must match'
  152.  
  153. login = fields.StringField('Username', validators=[validators.Length(message=username_message, min=4, max=25),
  154. validators.required(username_required)])
  155. email = fields.StringField('Email', validators=[validators.Length(message=email_address_message, max=60),
  156. validators.required(email_address_required)])
  157. password = fields.PasswordField('Password', validators=[validators.required(password_message),
  158. validators.EqualTo('confirm',
  159. message='Passwords must match')])
  160. confirm = fields.PasswordField('Repeat Password')
  161.  
  162. def validate_login(self, field):
  163. if db.session.query(User).filter_by(login=self.login.data).count() > 0:
  164. raise validators.ValidationError('Duplicate username')
  165. if db.session.query(User).filter_by(email=self.email.data).count() > 0:
  166. raise validators.ValidationError('Duplicate email')
  167.  
  168.  
  169. # Initialize flask-login
  170. def init_login():
  171. login_manager = login.LoginManager()
  172. login_manager.init_app(app)
  173.  
  174. # Create user loader function
  175. @login_manager.user_loader
  176. def load_user(user_id):
  177. return db.session.query(User).get(user_id)
  178.  
  179.  
  180. # Create customized model view class
  181. class MyModelView(sqla.ModelView):
  182. def is_accessible(self):
  183. if not current_user.is_active or not current_user.is_authenticated:
  184. return False
  185.  
  186. if current_user.has_role('superuser'):
  187. return True
  188.  
  189. return False
  190.  
  191. def _handle_view(self, name, **kwargs):
  192. """
  193. Override builtin _handle_view in order to redirect users when a view is not accessible.
  194. """
  195. if not self.is_accessible():
  196. if current_user.is_authenticated:
  197. # permission denied
  198. abort(403)
  199. else:
  200. # login
  201. return redirect(url_for('admin.login_view', next=request.url))
  202.  
  203.  
  204. class MyMasterIndexView(sqla.ModelView):
  205. def is_accessible(self):
  206. if not current_user.is_active or not current_user.is_authenticated:
  207. return False
  208.  
  209. if current_user.has_role('user'):
  210. return True
  211.  
  212. return False
  213.  
  214. def _handle_view(self, name, **kwargs):
  215. """
  216. Override builtin _handle_view in order to redirect users when a view is not accessible.
  217. """
  218. if not self.is_accessible():
  219. if current_user.is_authenticated:
  220. # permission denied
  221. abort(403)
  222. else:
  223. # login
  224. return redirect(url_for('admin.login_view', next=request.url))
  225.  
  226. # Delete hooks for models, delete files if models are getting deleted
  227. @listens_for(File, 'after_delete')
  228. def del_file(mapper, connection, target):
  229. if target.path:
  230. try:
  231. os.remove(op.join(file_path, target.path))
  232. except OSError:
  233. # Don't care if was not deleted because it does not exist
  234. pass
  235.  
  236. @listens_for(Image, 'after_delete')
  237. def del_image(mapper, connection, target):
  238. if target.path:
  239. # Delete image
  240. try:
  241. os.remove(op.join(file_path, target.path))
  242. except OSError:
  243. pass
  244.  
  245. # Delete thumbnail
  246. try:
  247. os.remove(op.join(file_path,
  248. form.thumbgen_filename(target.path)))
  249. except OSError:
  250. pass
  251.  
  252. # Administrative views
  253. '''
  254. class FileView(sqla.ModelView):
  255. # Override form field to use Flask-Admin FileUploadField
  256. form_overrides = {
  257. 'path': form.FileUploadField
  258. }
  259.  
  260. # Pass additional parameters to 'path' to FileUploadField constructor
  261. form_args = {
  262. 'path': {
  263. 'label': 'File',
  264. 'base_path': file_path,
  265. 'allow_overwrite': False
  266. }
  267. }
  268. '''
  269.  
  270.  
  271. class ImageView(sqla.ModelView):
  272. def _list_thumbnail(view, context, model, name):
  273. if not model.path:
  274. return ''
  275.  
  276. return Markup('<img src="%s">' % url_for('static',
  277. filename=form.thumbgen_filename(model.path)))
  278.  
  279. column_formatters = {
  280. 'path': _list_thumbnail
  281. }
  282.  
  283. # Alternative way to contribute field is to override it completely.
  284. # In this case, Flask-Admin won't attempt to merge various parameters for the field.
  285. form_extra_fields = {
  286. 'path': form.ImageUploadField('Image',
  287. base_path=file_path,
  288. thumbnail_size=(100, 100, True))
  289. }
  290.  
  291.  
  292.  
  293. # Create customized index view class that handles login & registration
  294. class MyAdminIndexView(admin.AdminIndexView):
  295. @expose('/')
  296. def index(self):
  297. if not login.current_user.is_authenticated:
  298. return redirect(url_for('.login_view'))
  299. return super(MyAdminIndexView, self).index()
  300.  
  301. @expose('/login/', methods=['GET', 'POST'])
  302. def login_view(self):
  303. # handle user login
  304. form = LoginForm(request.form)
  305. if helpers.validate_form_on_submit(form):
  306. user = form.get_user()
  307. login.login_user(user)
  308.  
  309. if login.current_user.is_authenticated:
  310. return redirect(url_for('.index'))
  311. link = '<p>Don't have an account? <a href="' + url_for('.register_view') + '">Click here to register.</a></p>'
  312. self._template_args['form'] = form
  313. self._template_args['link'] = link
  314. return super(MyAdminIndexView, self).index()
  315.  
  316. @expose('/register/', methods=['GET', 'POST'])
  317. def register_view(self):
  318. form = RegistrationForm(request.form)
  319. if helpers.validate_form_on_submit(form):
  320. user = User()
  321.  
  322. form.populate_obj(user)
  323. # we hash the users password to avoid saving it as plaintext in the db,
  324. # remove to use plain text:
  325. user.password = generate_password_hash(form.password.data)
  326.  
  327. db.session.add(user)
  328. db.session.commit()
  329.  
  330. login.login_user(user)
  331. return redirect(url_for('.index'))
  332. link = '<p>Already have an account? <a href="' + url_for('.login_view') + '">Click here to log in.</a></p>'
  333. self._template_args['form'] = form
  334. self._template_args['link'] = link
  335. return super(MyAdminIndexView, self).index()
  336.  
  337. @expose('/logout/')
  338. def logout_view(self):
  339. login.logout_user()
  340. return redirect(url_for('.index'))
  341.  
  342.  
  343. # Flask views
  344. @app.route('/')
  345. def index():
  346. return render_template('index.html')
  347.  
  348.  
  349. # Initialize flask-login
  350. init_login()
  351.  
  352. # Create admin
  353. admin = admin.Admin(app, index_view=MyAdminIndexView(), base_template='my_master.html')
  354.  
  355. # Add view
  356. admin.add_view(MyModelView(User, db.session))
  357. admin.add_view(MyModelView(Role, db.session))
  358. #admin.add_view(FileView(File, db.session))
  359. admin.add_view(ImageView(Image, db.session, name='Order'))
  360.  
  361.  
  362. # define a context processor for merging flask-admin's template context into the
  363. # flask-security views.
  364. @security.context_processor
  365. def security_context_processor():
  366. return dict(
  367. admin_base_template=admin.base_template,
  368. admin_view=admin.index_view,
  369. h=admin_helpers,
  370. get_url=url_for
  371. )
  372.  
  373.  
  374. def build_sample_db():
  375. """
  376. Populate a small db with some example entries.
  377. """
  378.  
  379. db.create_all()
  380.  
  381. with app.app_context():
  382. user_role = Role(name='user')
  383. super_user_role = Role(name='superuser')
  384. db.session.add(user_role)
  385. db.session.add(super_user_role)
  386. db.session.commit()
  387.  
  388. test_user = user_datastore.create_user(
  389. login='Admin',
  390. email='admin',
  391. password=generate_password_hash('admin'),
  392. roles=[super_user_role]
  393. )
  394. db.session.add(test_user)
  395. db.session.commit()
  396.  
  397. return
  398.  
  399.  
  400. if __name__ == '__main__':
  401. # Build a sample db on the fly, if one does not exist yet.
  402. app_dir = os.path.realpath(os.path.dirname(__file__))
  403. database_path = os.path.join(app_dir, app.config['DATABASE_FILE'])
  404. if not os.path.exists(database_path):
  405. build_sample_db()
  406.  
  407. # Start app
  408. app.run(debug=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement