当前位置:  开发笔记 > 编程语言 > 正文

flask admin单击时编辑子对象

如何解决《flaskadmin单击时编辑子对象》经验,为你挑选了1个好方法。

Flask-Admin在其标准编辑视图中显示由关系定义的子对象。例如,如果User对象有Address子对象,则查看的编辑视图UserAddress在适当的字段中显示子对象。然后,用户可以删除该对象,或添加另一个对象。

我希望用户能够单击或以其他方式进入子对象的编辑视图。在我描述的示例中,用户应该能够Address直接从对象的编辑视图访问对象的编辑视图User

我发现的唯一相关内容是inline_models,但这不是解决方案。该实现非常脆弱(例如,它不能处理长距离关系)。Flask-Admin知道子对象!我可以在视图中看到它们!我只希望他们成为他们自己的编辑视图的链接...

任何人都知道如何实现这一目标,或者可以链接到示例吗?



1> pjcunningham..:

这是一个在编辑视图中放置指向另一个模型的编辑视图的链接的简单文件示例。它可能对您有帮助。

我已经使用了用户-地址关系,一个用户有一个地址,而地址可以有许多用户。

我已经使用Faker生成示例数据,因此您需要pip install faker进入您的环境。

这个想法是使用Flask-Admin 表单规则,在这种情况下,我正在配置form_edit_rules

我创建了两个自定义规则:

Link,继承BaseRule。构造函数采用三个值;端点,属性名称将与Flask url_for方法中的端点一起传递,最后文本将显示为链接。在此示例中,端点是'address.edit_view'因为这是我们要链接的视图。

MultiLink,类似于Link接受它与关系的关系。

这是代码(几乎没有错误检查):

from random import randint
from flask import Flask, url_for
from flask_admin.contrib import sqla
from flask_admin import Admin
from flask_admin.form.rules import BaseRule
from faker import Faker
from flask_sqlalchemy import SQLAlchemy
from markupsafe import Markup
from sqlalchemy import func, select
from sqlalchemy.ext.hybrid import hybrid_property

fake = Faker()

# Create application
app = Flask(__name__)

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

# Create in-memory database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
# app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


# Flask views
@app.route('/')
def index():
    return 'Click me to get to Admin!'


class Address(db.Model):

    __tablename__ = 'addresses'

    id = db.Column(db.Integer, primary_key=True)
    number = db.Column(db.String(255))
    street = db.Column(db.String(255))
    city = db.Column(db.String(255))
    country = db.Column(db.String(255))

    @hybrid_property
    def user_count(self):
        return len(self.users)

    @user_count.expression
    def user_count(cls):
        return select([func.count(User.id)]).where(User.address_id == cls.id).label("user_count")

    def __unicode__(self):
        return ', '.join(filter(None, [self.number, self.street, self.city, self.country]))


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(255))
    last_name = db.Column(db.String(255))
    email = db.Column(db.String(254))

    address_id = db.Column(db.Integer, db.ForeignKey('addresses.id'), index=True)
    address = db.relationship(Address, backref=db.backref('users'))

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

    def __unicode__(self):
        return '{} {}'.format(self.first_name, self.last_name)


class Link(BaseRule):
    def __init__(self, endpoint, attribute, text):
        super(Link, self).__init__()
        self.endpoint = endpoint
        self.text = text
        self.attribute = attribute

    def __call__(self, form, form_opts=None, field_args={}):

        _id = getattr(form._obj, self.attribute, None)

        if _id:
            return Markup('{text}'.format(url=url_for(self.endpoint, id=_id), text=self.text))


class MultiLink(BaseRule):
    def __init__(self, endpoint, relation, attribute):
        super(MultiLink, self).__init__()
        self.endpoint = endpoint
        self.relation = relation
        self.attribute = attribute

    def __call__(self, form, form_opts=None, field_args={}):

        _hrefs = []
        _objects = getattr(form._obj, self.relation)
        for _obj in _objects:
            _id = getattr(_obj, self.attribute, None)
            _link = 'Edit {text}'.format(url=url_for(self.endpoint, id=_id), text=str(_obj))
            _hrefs.append(_link)

        return Markup('
'.join(_hrefs)) class UserAdmin(sqla.ModelView): can_view_details = True form_edit_rules = ( 'first_name', 'last_name', 'email', 'address', Link(endpoint='address.edit_view', attribute='address_id', text='Edit Address') ) class AddressAdmin(sqla.ModelView): can_view_details = True column_list = ['number', 'street', 'city', 'country', 'user_count', 'users'] form_edit_rules = ( 'number', 'street', 'city', 'country', 'users', MultiLink(endpoint='user.edit_view', relation='users', attribute='id') ) admin = Admin(app, template_mode="bootstrap3") admin.add_view(UserAdmin(User, db.session)) admin.add_view(AddressAdmin(Address, db.session)) def build_db(): db.drop_all() db.create_all() for _ in range(0, 20): _users = [] for _ in range(0, randint(1, 10)): _user = User( first_name=fake.first_name(), last_name=fake.last_name(), email=fake.safe_email(), ) _users.append(_user) _address = Address( number=fake.random_digit_not_null(), street=fake.secondary_address(), city=fake.city(), country=fake.country(), users = _users ) db.session.add(_address) db.session.commit() @app.before_first_request def first_request(): build_db() if __name__ == '__main__': app.run(port=5000, debug=True)

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有