Flask-Admin upload and insert in database automatically
Asked Answered
P

1

7

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 ?

Pun answered 9/10, 2013 at 14:15 Comment(2)
How are you adding users and uploading photo ? Are you using 2 different views ? can you share some code ?Midsection
My Admin panel's views are like this: pastebin.com/9J6pEA0Z . As you can imagine, it will render a separate view for Content and FileUpload (which I want to merge, so that when I add a content the url will be the same as the uploaded file) Thnks!Pun
U
8

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!

Unloose answered 20/11, 2014 at 19:57 Comment(1)
pic in User class should be a string with a path name, otherwise if this becomes a large project, storing lots of LargeBinary in a database can get pretty expensive.Frech

© 2022 - 2024 — McMap. All rights reserved.