用于Flask微框架的HTML表格
项目描述
Flask Table
因为编写HTML很麻烦,而你所有的表格基本上都是相同的。
快速入门
# import things
from flask_table import Table, Col
# Declare your table
class ItemTable(Table):
name = Col('Name')
description = Col('Description')
# Get some objects
class Item(object):
def __init__(self, name, description):
self.name = name
self.description = description
items = [Item('Name1', 'Description1'),
Item('Name2', 'Description2'),
Item('Name3', 'Description3')]
# Or, equivalently, some dicts
items = [dict(name='Name1', description='Description1'),
dict(name='Name2', description='Description2'),
dict(name='Name3', description='Description3')]
# Or, more likely, load items from your database with something like
items = ItemModel.query.all()
# Populate the table
table = ItemTable(items)
# Print the html
print(table.__html__())
# or just {{ table }} from within a Jinja template
给出类似的结果
<table>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td>Name1</td><td>Description1</td></tr>
<tr><td>Name2</td><td>Description2</td></tr>
<tr><td>Name3</td><td>Description3</td></tr>
</tbody>
</table>
其他功能
在列的声明中使用每个列的属性用作查找每个项目的默认项。
填充表格时传递的项必须是可迭代的
包含字典或对象 - 没有规定它不能同时包含一些。
请参阅examples/simple_sqlalchemy.py以获取数据库示例。
您可以通过在创建Col时传递属性字典作为td_html_attrs或th_html_attrs来向td和th元素传递属性。或者作为column_html_attrs将属性应用于th和td。 (任何传递给th_html_attrs或td_html_attrs的属性将覆盖任何也传递给column_html_attrs的属性。) 请参阅examples/column_html_attrs.py以获取更多信息。
还有LinkCol和ButtonCol允许链接和按钮,这就是Flask特定的部分。
还有DateCol和DatetimeCol可以格式化日期和时间。
还有BoolCol,它可以显示是/否。
但最重要的是,Col很容易进行子类化。
表格配置和选项
以下选项配置了表格级别的选项
thead_classes - 设置在<thead>元素上的类列表。
no_items - 如果未传递任何项目时显示的字符串,默认为 'No Items'。
html_attrs - 一个字典,用于设置 <table> 元素的属性。
classes - 一个字符串列表,将作为 <table> 元素的 class 属性设置。
table_id - 一个字符串,将作为 <table> 元素的 id 属性设置。
border - 是否应在 <table> 元素上设置边框。
可以通过几种不同的方式设置这些属性
在定义表格类时设置
class MyTable classes = ['class1', 'class2']
在 create_table 函数的 options 参数中传递
MyTable = create_table(options={'table_id': 'my-table-id'})
传递给表格的 __init__
table = MyTable(items, no_items='There is nothing', ...)
注意,a) 和 b) 定义了表格类的属性,但 c) 定义了实例的属性,因此像 c) 中设置的内容将覆盖 a) 或 b) 中设置的内容。
例如
class ItemTable(Table):
classes = ['myclass']
name = Col('Name')
table = ItemTable(items, classes=['otherclass'])
将创建一个具有 class="otherclass" 的表格。
包含的列类型
`OptCol` <#more-about-optcol>`__ - 根据选择的字典转换值。例如,将存储的代码转换为可读文本。
`BoolCol` <#more-about-boolcol>`__ (OptCol 的子类) - 将值转换为是/否。
`BoolNaCol` <#more-about-boolnacol>`__ (BoolCol 的子类) - 将值转换为是/否/na。
`DateCol` <#more-about-datecol>`__ - 用于日期(使用 format_date 从 babel.dates)。
`DatetimeCol` <#more-about-datetimecol>`__ - 用于日期时间(使用 format_datetime 从 babel.dates)。
`LinkCol` <#more-about-linkcol>`__ - 通过指定端点和 url_kwargs 创建链接。
`ButtonCol` <#more-about-buttoncol>`__ (LinkCol 的子类) 创建一个按钮,将提交给指定的地址。
`NestedTableCol` <#more-about-nestedtablecol>`__ - 允许在列内嵌套表格。
关于 OptCol 的更多信息
创建列时,您传递一些 choices。这应该是一个字典,键是将在项目的属性中找到的值,值是要显示的文本。
您还可以设置 default_key 或 default_value。如果从项目中发现的价值不在选择字典中,则将使用默认值。默认键以类似的方式工作,但意味着如果您的默认值已经在您的选择中,您可以直接指向它而不是重复它。
如果您需要在查找字典之前更改项目中的值,可以使用 coerce_fn。
关于 BoolCol 的更多信息
这是一个 OptCol 的子类,其中 choices 为
{True: 'Yes', False: 'No'}
并且 coerce_fn 是 bool。因此,项目的值被转换为 bool,然后在该选择中查找以获取要显示的文本。
如果您想指定“是”和“否”之外的内容,可以在创建列时传递 yes_display 和/或 no_display。例如
class MyTable(Table):
mybool = BoolCol('myboolcol', yes_display='Affirmative', no_display='Negatory')
关于 BoolNaCol 的更多信息
类似于 BoolCol,但显示 None 为“N/A”。可以使用 na_display 参数进行覆盖。
关于 DateCol 的更多信息
从项目格式化日期。可以指定要使用的 date_format,默认为 'short',它被传递给 babel.dates.format_date。
关于 DatetimeCol 的更多信息
从项目格式化 datetime。可以指定要使用的 datetime_format,默认为 'short',它被传递给 babel.dates.format_datetime。
关于 LinkCol 的更多信息
提供在 td 中放置链接的方法。您必须指定一个用于 url 的 endpoint。还应指定一些 url_kwargs。这将是一个字典,将被作为 url_for 的第二个参数传递,除了值将被视为要查找项的属性。这些键遵守相同的规则,因此可以是类似 'category.name' 或 ('category', 'name') 的事物。
关键字参数 url_kwargs_extra 允许向 url 传递常量。这可以用于向 url 添加常量 GET 参数。
链接文本的获取方式几乎与其它列相同。但是,其他列可以不提供 attr 或 attr_list,并使用列在表类中提供的属性,但 LinkCol 不这样做,而是回退到列标题。这对像“编辑”链接这样的东西更有意义。您可以使用 text_fallback 关键字参数覆盖此回退。
通过传递 anchor_attrs 来设置锚标签的属性
name = LinkCol('Name', 'single_item', url_kwargs=dict(id='id'), anchor_attrs={'class': 'myclass'})
关于 NestedTableCol 的更多信息
此列类型使得在列中嵌套表成为可能。对于每个嵌套表列,您需要定义一个子类 Table,就像您在定义表时通常所做的那样。那个 Table 子类的名称是 NestedTableCol 的第二个参数。
例如
class MySubTable(Table):
a = Col('1st nested table col')
b = Col('2nd nested table col')
class MainTable(Table):
id = Col('id')
objects = NestedTableCol('objects', MySubTable)
子类化 Col
(在 examples/subclassing.py 中查找更具体的示例)
假设我们的项目有一个属性,但我们不想直接输出值,我们需要先修改它。如果我们从项中获得的价值提供了我们所需的所有信息,那么我们只需覆盖 td_format 方法即可
class LangCol(Col):
def td_format(self, content):
if content == 'en_GB':
return 'British English'
elif content == 'de_DE':
return 'German'
elif content == 'fr_FR':
return 'French'
else:
return 'Not Specified'
如果您需要访问项中的所有信息,那么我们可以回溯到过程的更早阶段,并覆盖 td_contents 方法
from flask import Markup
def td_contents(self, i, attr_list):
# by default this does
# return self.td_format(self.from_attr_list(i, attr_list))
return Markup.escape(self.from_attr_list(i, attr_list) + ' for ' + item.name)
目前,您在覆盖这些方法时仍需要小心转义。另外,由于 Markup 类的工作方式,您需要小心地将这些与其他字符串连接起来。
操作 <tr>
(在 examples/rows.py 中查找更具体的示例)
假设您想更改tr元素的一些或全部项的内容。您可以通过覆盖您表格的get_tr_attrs方法来实现。默认情况下,此方法返回一个空字典。
因此,我们可能想要使用类似下面的方法
class ItemTable(Table):
name = Col('Name')
description = Col('Description')
def get_tr_attrs(self, item):
if item.important():
return {'class': 'important'}
else:
return {}
这将给所有返回important()方法为真值的tr项添加一个“important”类。
动态创建表格
(更具体的示例请查看examples/dynamic.py)
您也可以动态定义一个表格。
TableCls = create_table('TableCls')\
.add_column('name', Col('Name'))\
.add_column('description', Col('Description'))
这与以下代码等价
class TableCls(Table):
name = Col('Name')
description = Col('Description')
但使得动态添加列变得更容易。
例如,您可能希望根据条件只添加一个列。
TableCls = create_table('TableCls')\
.add_column('name', Col('Name'))
if condition:
TableCls.add_column('description', Col('Description'))
这与以下代码等价
class TableCls(Table):
name = Col('Name')
description = Col('Description', show=condition)
这得益于show选项。使用您认为可以使代码更易读的选项。虽然您可能仍然需要动态选项来处理类似的情况
TableCls = create_table('TableCls')
for i in range(num):
TableCls.add_column(str(i), Col(str(i)))
我们还可以通过向create_table()函数传递options参数来设置表格类的某些额外选项
tbl_options = dict(
classes=['cls1', 'cls2'],
thead_classes=['cls_head1', 'cls_head2'],
no_items='Empty')
TableCls = create_table(options=tbl_options)
# equals to
class TableCls(Table):
classes = ['cls1', 'cls2']
thead_classes = ['cls_head1', 'cls_head2']
no_items = 'Empty'
可排序表格
(更具体的示例请查看examples/sortable.py)
定义一个表格并将它的allow_sort属性设置为True。现在所有列默认会尝试将其标题转换为链接以进行排序,除非您将该列的allow_sort设置为False。
您还必须声明一个sort_url方法来处理该表格。给定一个col_key,这将确定标题中链接的URL。如果reverse为True,则表示该表格刚刚按该列排序,URL可以相应调整,即现在给出按反向方向排序的地址。然而,如何解释从该URL传给flask视图方法的值并排序结果,完全取决于您的flask视图方法。表格本身不会对其给出的项进行重新排序。
class SortableTable(Table):
name = Col('Name')
allow_sort = True
def sort_url(self, col_key, reverse=False):
if reverse:
direction = 'desc'
else:
direction = 'asc'
return url_for('index', sort=col_key, direction=direction)
示例
examples目录包含一些示例代码,以展示一些概念和功能。它们都是可以运行的。其中一些仅输出它们生成的代码,但一些(目前只有sortable.py)实际上创建了一个可以访问的Flask应用程序。
您应该可以直接使用python运行它们,但如果您为了开发目的克隆了存储库并创建了一个虚拟环境,您可能会发现它们生成一个对flask_table的导入错误。这是因为flask_table尚未安装,可以通过运行类似以下命令来修复:PYTHONPATH=.:./lib/python3.3/site-packages python examples/simple.py,这将使用本地的flask_table版本,包括任何更改。
此外,如果您认为有任何内容不清晰,并且可以通过示例来帮助,请随时询问,我将很高兴编写一个示例。只有您才能帮助我识别哪些部分比较棘手或不太明显,并帮助我解释需要解释的部分。
其他事项
在首次编写时,我并不了解Django-Tables的工作。然而,我现在已经找到了它,并开始根据需要采用其中的想法。例如,允许项既是字典又是对象。
项目详情
Flask-Table-0.5.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 320e5756cd7252e902e03b6cd1087f2c7ebc31364341b482f41f30074d10a770 |
|
MD5 | e1d31040efa020013d0867df0bde8828 |
|
BLAKE2b-256 | 5cf8c8680277a8a0170d6f4c170dc4525f7869134021549eb84b116a75a24b15 |