【问题标题】:Flask-admin how to add button beside rowsFlask-admin如何在行旁边添加按钮
【发布时间】:2019-01-26 13:46:08
【问题描述】:

我使用 Flask 制作了一个学费支付应用,并使用 Flask-admin 来管理付款。

Flask-Admin 由我在 models.py 中声明的 SQLAlchemy 自动生成表行

这是我的桌子的图像: 现在我想在每个总帐单号码旁边加一个按钮,以便结帐。

我知道如何使用 ModelView 提供的 column_list 方法添加列,因为我尝试如下代码:

column_list = ('student_id', 'total_bill', 'Pay Now')

它会给视图显示如下: 现在我希望列 Pay Now 对每一行都有一个按钮,就像我使用 HTML 手动编码一样,如下所示: 每行都有一个结帐按钮,正如我上面提到的,这个目的是为结帐按钮。

那么,如何做到这一点..?,任何帮助将不胜感激

【问题讨论】:

标签: python flask flask-sqlalchemy flask-login flask-admin


【解决方案1】:

您可以使用column_formatters 以任何您希望的方式呈现列。

Github 上的示例代码,flask-admin-row-form

例如,每一行“结帐”按钮都可以呈现为带有提交按钮的 HTML 表单,而学生 ID 则呈现为表单中的隐藏字段。

下面的简单示例(Python 2.7),文件都驻留在根目录中。 views.py 包含重要代码,其余的都是简单的 Flask 代码。

StudentView 定义了一个方法_format_pay_now,如果模型的is_paid 值为True 或HTML 表单,则该方法呈现一个字符串“Paid”。

StudentView 类还通过checkout_view 方法公开了一个路由'/admin/student/checkout' 来处理提交的表单。在此特定实例中,is_paid 列设置为 True,并且重新呈现列表视图。

views.py

from flask import redirect, flash, url_for
from flask_admin import expose
from flask_admin.contrib import sqla
from flask_admin.helpers import get_form_data
from flask_admin.babel import gettext
from markupsafe import Markup


class StudentView(sqla.ModelView):

    page_size = 5

    column_list = ('id', 'cost', 'Pay Now')
    column_editable_list = ['cost']

    # override the column labels
    column_labels = {
        'id': 'Student ID',
        'cost': 'Total Bill',
    }

    def _format_pay_now(view, context, model, name):

        if model.is_paid:
            return 'Paid'

        # render a form with a submit button for student, include a hidden field for the student id
        # note how checkout_view method is exposed as a route below
        checkout_url = url_for('.checkout_view')

        _html = '''
            <form action="{checkout_url}" method="POST">
                <input id="student_id" name="student_id"  type="hidden" value="{student_id}">
                <button type='submit'>Checkout</button>
            </form
        '''.format(checkout_url=checkout_url, student_id=model.id)

        return Markup(_html)

    column_formatters = {
        'Pay Now': _format_pay_now
    }

    @expose('checkout', methods=['POST'])
    def checkout_view(self):

        return_url = self.get_url('.index_view')

        form = get_form_data()

        if not form:
            flash(gettext('Could not get form from request.'), 'error')
            return redirect(return_url)

        # Form is an ImmutableMultiDict
        student_id = form['student_id']

        # Get the model from the database
        model = self.get_one(student_id)

        if model is None:
            flash(gettext('Student not not found.'), 'error')
            return redirect(return_url)

        # process the model
        model.is_paid = True

        try:
            self.session.commit()
            flash(gettext('Student, ID: {student_id}, set as paid'.format(student_id=student_id)))
        except Exception as ex:
            if not self.handle_view_exception(ex):
                raise

            flash(gettext('Failed to set student, ID: {student_id}, as paid'.format(student_id=student_id), error=str(ex)), 'error')

        return redirect(return_url)

models.py

from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    cost = db.Column(db.Integer(), nullable=False)
    is_paid = db.Column(db.Boolean(), nullable=False)

    def __str__(self):
        return unicode(self).encode('utf-8')

    def __unicode__(self):
        return "ID: {id}; Cost : {cost}".format(id=self.id, cost=self.cost)

commands.py

使用flask create-database 生成SQLite 数据库。

import random
from flask.cli import click, with_appcontext
from models import db, Student


@click.command('create-database')
@with_appcontext
def create_database():

    # Create 100 students

    db.drop_all()
    db.create_all()

    for _ in range(0, 100):
        _project = Student(
            cost=random.randrange(10, 200),
            is_paid=False
        )
        db.session.add(_project)

    db.session.commit()

app.py

from flask import Flask
from flask_admin import Admin
from models import db, Student
from commands import create_database

app = Flask(__name__)

# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
db.init_app(app)

app.cli.add_command(create_database)


# Flask views
@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'


from views import StudentView

admin = Admin(app, template_mode="bootstrap3")
admin.add_view(StudentView(Student, db.session))


if __name__ == '__main__':
    app.run()

requirements.txt

Click==7.0
enum34==1.1.6
Flask==1.0.2
Flask-Admin==1.5.3
Flask-SQLAlchemy==2.3.2
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
SQLAlchemy==1.2.17
Werkzeug==0.14.1
WTForms==2.2.1

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 2019-01-13
    • 2013-09-16
    • 2016-03-21
    • 1970-01-01
    • 2019-12-20
    • 2012-08-06
    • 2018-06-04
    相关资源
    最近更新 更多