Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-Admin upload and insert in database automatically

My user is modeled in SQLAlchemy as:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    url_pic = Column(String(50), nullable=False)
    (...)

And I want to add the user to the database in Flask-Admin in such a way that when I create the user, I can upload directly the photo and the destination url is parsed and passed for the url_pic field in the database.

I already can add users and upload photos (well explain at https://flask-admin.readthedocs.org/en/latest/quickstart/ ), but couldn't find any information on how to merge the add user and photo uploading in the same view.

Any clue ?

like image 671
gpestana Avatar asked Oct 09 '13 14:10

gpestana


1 Answers

You can modify your model to look like this:

class User(Base):
   __tablename__ = 'users'
   id = Column(Integer, primary_key=True)
   url_pic = Column(String(50), nullable=False)
   pic = Column(LargeBinary, nullable=False)
   ...

Now you should subclass ModelView from flask.ext.admin.contrib.sqla. Then you add an instance of that subclass to the Admin instance. The following source code could help you to get the point.

from flask.ext.admin.contrib.sqla import ModelView
from flask.ext.admin.form.upload import FileUploadField
from wtforms.validators import ValidationError
from flask.ext.admin import Admin
from flask.ext.sqlalchemy import SQLAlchemy
from flask import Flask
import imghdr

app = Flask(__name__)
db = SQLAlchemy(app)

class UserAdminView(ModelView):

   def picture_validation(form, field):
      if field.data:
         filename = field.data.filename
         if filename[-4:] != '.jpg': 
            raise ValidationError('file must be .jpg')
         if imghdr.what(field.data) != 'jpeg':
            raise ValidationError('file must be a valid jpeg image.')
      field.data = field.data.stream.read()
      return True

   form_columns = ['id','url_pic', 'pic']
   column_labels = dict(id='ID', url_pic="Picture's URL", pic='Picture')

   def pic_formatter(view, context, model, name):
       return 'NULL' if len(getattr(model, name)) == 0 else 'a picture'

   column_formatters =  dict(pic=pic_formatter)
   form_overrides = dict(pic= FileUploadField)
   form_args = dict(pic=dict(validators=[picture_validation]))

admin = Admin(app)
admin.add_view(UserAdminView(User, db.session, category='Database Administration'))
...

Here you can find the docs for ModelView: link here I hope this can help someone!

like image 74
Giova Avatar answered Sep 29 '22 19:09

Giova