gpt4 book ai didi

python - Flask 管理员单击时编辑子对象

转载 作者:行者123 更新时间:2023-12-02 06:13:32 28 4
gpt4 key购买 nike

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

我希望用户能够单击,或者能够进入子对象的编辑 View 。在我描述的示例中,用户应该能够直接从 User 对象的编辑 View 访问 Address 对象的编辑 View 。

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

任何人都知道如何实现此目的或可以链接到示例吗?

最佳答案

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

enter image description here

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

我已使用 Faker 生成示例数据,因此您需要将 pip install faker 添加到您的环境中。

这个想法是使用 Flask-Admin form rules,在本例中我正在配置 form_edit_rules

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

Link,继承BaseRule。构造函数采用三个值;一个端点、与 Flask url_for 方法中的端点一起传递的属性名称,最后是显示为链接的文本。在此示例中,端点为'address.edit_view',因为这是我们要链接到的 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 '<a href="/admin/">Click me to get to Admin!</a>'


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=None):
if not field_args
field_args = {}

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

if _id:
return Markup('<a href="{url}">{text}</a>'.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=None):
if not field_args
field_args = {}
_hrefs = []
_objects = getattr(form._obj, self.relation)
for _obj in _objects:
_id = getattr(_obj, self.attribute, None)
_link = '<a href="{url}">Edit {text}</a>'.format(url=url_for(self.endpoint, id=_id), text=str(_obj))
_hrefs.append(_link)

return Markup('<br>'.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)

关于python - Flask 管理员单击时编辑子对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42962887/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com