烧瓶,WTForm,关系

时间:2016-08-19 13:20:05

标签: flask sqlalchemy flask-sqlalchemy wtforms flask-wtforms

我正在尝试创建与父模型Article相关的图库。我有两个模型,一个用于存储上传的文件,另一个用于存储由image_shots.articles.id链接的已发布文章。

以下是我的模特:

class Media(db.Model):
    __tablename__ = 'media'
    id = db.Column(db.Integer, primary_key=True)
    caption = db.Column(db.String(500))
    article = db.Column(db.Integer, db.ForeignKey('articles.id'), index=True)
    posted_date = db.Column(db.DateTime)

    def __init__(self, **kwargs):
        super(Media, self).__init__(**kwargs)

class Article(db.Model):
    __tablename__ = 'articles'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(400))
    body = db.Column(db.Text)
    updated_on = db.Column(db.DateTime)
    view_count = db.Column(db.Integer)

    image_shots = db.relationship("Media", backref="articles")

    def __init__(self, **kwargs):
        super(Article, self).__init__(**kwargs)

这是我的表格:

from flask_wtf import Form, validators
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired, Length

class ArticleForm(Form):
    title = StringField('Title', validators=[DataRequired(), Length(1, 64), ])
    description = TextAreaField(u'Description', [validators.optional(), validators.length(max=200)])
    file = FileField()

以下是我的观点:

@articles.route('/new', methods=['GET', 'POST'])
def articles():
     form = ArticleForm()
     articles = [title for title, in db.session.query(Article)]
     if request.method == 'POST'and form.validate_on_submit():
         article = Article(title=form.name.data)
         db.session.add(article)
         db.session.commit()
         flash(message='Article successfully added')
         return redirect(url_for('articles.index'))
     elif request.method == 'GET':
         articles = [title for title, in db.session.query(Article)]
     return render_template('front/articles.html', articles=articles, form=form)

有了这个,我就可以保存已发布的文章,但我仍然对如何获取上传的文件感到困惑,然后将articles.id作为外键保存在自己的模型中。

小细节,我需要在同一文章表单中上传多个形成图库的文件。它们如何联系起来?

1 个答案:

答案 0 :(得分:0)

我现在正在做的项目有类似的问题。它是一个专辑网站,用户创建一个专辑并将多个文件上传到这个专辑。

这是我的解决方案。

模特:

# import ...
class Photo(db.Model):
    __tablename__ = 'photos'
    id = db.Column(db.Integer, primary_key=True)
    path = db.Column(db.Text)
    about = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    album_id = db.Column(db.Integer, db.ForeignKey('albums.id'))

class Album(db.Model):
    __tablename__ = 'albums'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Text)
    about = db.Column(db.Text)
    cover = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    photos = db.relationship('Photo', backref='album', lazy='dynamic')

形式:

# import ...
from flask_wtf.file import FileField, FileAllowed, FileRequired

class NewAlbumForm(Form):
    title = StringField('Title')
    about = TextAreaField('About')
    photo = FileField('Photo', validators=[
    FileRequired(),
    FileAllowed(photos, 'Image Only!')
])
    submit = SubmitField('Submit')

查看:

#import ...

@main.route('/new', methods=['GET', 'POST']) # create new album, like yours.
def create():
    from flask_uploads import UploadSet, configure_uploads, IMAGES
    app = current_app._get_current_object()
    photos = UploadSet('photos', IMAGES)
    form = NewAlbumForm()
    if form.validate_on_submit():
        if request.method == 'POST' and 'photo' in request.files:
            filename=[]
            for img in request.files.getlist('photo'): # upload multiple files.
                photos.save(img)
                url = photos.url(img.filename)
                filename.append(url)
        title = form.title.data
        about = form.about.data
        author = current_user._get_current_object()
        album = Album(title=title, about=about,
            cover=filename[0], # use first file as album cover
            author = current_user._get_current_object())
        db.session.add(album)

        for file in filename:
            photo = Photo(path=file, album=album) # save image path.
            db.session.add(photo)
        db.session.commit()
        return redirect(url_for('.album', id=album.id))
    return render_template('new.html', form=form)


@main.route('/user/<username>/albums') # show albums created by user
def albums(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        abort(404)
    albums = user.albums.order_by(Album.timestamp.desc()).all()
    album_count = len(albums)
    return render_template('albums.html', user=user, albums=albums, album_count=album_count)


@main.route('/album/<int:id>') # show photos in an album
def album(id):
    album = Album.query.get_or_404(id)
    photos = album.photos.order_by(Photo.timestamp.asc())
    return render_template('album.html', album=album, photos=photos)

在模板中,我使用for循环来生成图像gallary。像这样:

/* route: /album/<int:id> */
<div class="container">
  <div class="row">
    {% for photo in photos %}
    <div class="item">     
      <a class="thumbnail" href="">
       <img class="img-responsive" src="{{ photo.path }}">
      </a>
    </div>
    {% endfor %}
  </div>
</div>

我使用Flask-Uploads上传多个文件,您可以查看this answer。此外,我使用isotope对照片进行排序 可能有点复杂,你可以问任何你想问的问题:)