django_tables2 是一个django的插件,可以很方便的构建表类型的数据。
最近使用过程中遇到一些问题,这里记录一下。
0x01 系统环境
django:django.1.9.8
django_tables2: django_tables2-1.16.0-py2.7
0x02 使用问题
- 使用自定义table模板:
最新的django_tables2文档中,默认使用的table模板是在django_tables2安装目录下templates/django_tables2/table.html。
如果要更换其他模板,在class Meta中添加template_name赋值操作:
class PersonTable(tables.Table):
class Meta:
model = Person
template_name = 'django_tables2/semantic.html'
在django_tables2-1.16.0版本中,要更换其他模板,应该是class Meta 中template(而不是template_name)
class PersonTable(tables.Table):
class Meta:
model = Person
template = 'django_tables2/semantic.html'
可以通过查看源码查看,在django_tables2的tables.py文件中:
class TableOptions(object):
'''
Extracts and exposes options for a `.Table` from a `.Table.Meta`
when the table is defined. See `.Table` for documentation on the impact of
variables in this class.
Arguments:
┆ options (`.Table.Meta`): options for a table from `.Table.Meta`
'''
def __init__(self, options=None):
┆ super(TableOptions, self).__init__()
n ┆ DJANGO_TABLES2_TEMPLATE = getattr(settings, 'DJANGO_TABLES2_TEMPLATE', 'django_tables2/table.html')
┆ DJANGO_TABLES2_TABLE_ATTRS = getattr(settings, 'DJANGO_TABLES2_TABLE_ATTRS', {})
...
┆ self.template = getattr(options, 'template', DJANGO_TABLES2_TEMPLATE)
上面的类中可以看到,模板是又self.template控制的,而默认模板是又DJANGO_TABLES2_TEMPLATE指定的。
- table类型的数据获取num_pages:
用django_tables2的指导文档的例子来说明一下:
新建一个person的model
# tutorial/models.py
class Person(models.Model):
name = models.CharField(max_length=100, verbose_name='full name')
创建数据库
$ python manage.py makemigrations tutorial
$ python manage.py migrate tutorial
添加数据
$ python manage.py shell
>>> from tutorial.models import Person
>>> Person.objects.bulk_create([Person(name='Jieter'), Person(name='Bradley')])
[<Person: Person object>, <Person: Person object>]
编写person view
# tutorial/views.py
from django.shortcuts import render
from .models import Person
def people(request):
return render(request, 'tutorial/people.html', {'people': Person.objects.all()})
添加url与view的映射
# urls.py
from django.conf.urls import url
from django.contrib import admin
from tutorial.views import people
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^people/', people)
]
添加模板
{# tutorial/templates/tutorial/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List of persons</title>
</head>
<body>
{% render_table people %}
</body>
</html>
从这个例子可以看出:
- 模板中的render_tables可以传递queryset类型的数据,即Person.objects.all()
- 传递queryset类型数据,无法支持数据的排序和分页。
- 更换一下,使用django_tables2的tables类型数据,而不使用queryset数据。
生成model
# tutorial/tables.py
import django_tables2 as tables
from .models import Person
class PersonTable(tables.Table):
class Meta:
model = Person
template_name = 'django_tables2/bootstrap.html'
生成view
# tutorial/views.py
from django.shortcuts import render
from django_tables2 import RequestConfig
from .models import Person
from .tables import PersonTable
def people(request):
table = PersonTable(Person.objects.all())
RequestConfig(request).configure(table)
return render(request, 'people.html', {'table': table})
生成模板
{# tutorial/templates/tutorial/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List of persons</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body>
{% render_table table %}
</body>
</html>
结果如下:
如果要使用分页,可以使用table对象的paginator属性。如果在模板中我们要获取分页的最大页码,添加代码
{{table.paginator.num_pages}}
即可,例如:
{# tutorial/templates/tutorial/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List of persons</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body>
{% render_table table %}
<p>{{table.paginator.num_pages}}<p>
</body>
</html>
0x03 最后用一个实际的例子说明:
需求如下:
有一个jump链接标签,一个输入页码框,可以跳转到任意分页,如果输入的页码大于最大的分页,这跳转到最后一个页。
{# tutorial/templates/tutorial/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List of persons</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body>
{% render_table table %}
<a id="jump_num" href="">Jump</a>
<input type=text id="pagenum">
</body>
</html>
当input触发了change事件,就修改jump_num链接标签的值,这样点击jump链接,就跳转到了相应的分页,如果输入的值大于分页最大值,就可以使用上面讲到的获取最大分页的方法。(备注:这里js不能使用input事件$('#pagenum').on("input", function()
因为change是在输入完数据失去焦点触发的,而input是每输入或者删除一个字符都会触发,并不需要失去焦点。)
$('#pagenum').change(function() {
var pagenum = document.getElementById('pagenum').value;
var jump = document.getElementById('jump_num')
if(pagenum > 0)
{
┆ jump.href = "?page=" + pagenum
}
if (pagenum > {{table.paginator.num_pages }})
{
┆ jump.href = "?page=" + {{ table.paginator.num_pages }}
}
┆ //alert("Page num is error");
});
0x04 总结
-
django_tables2 修改默认模板:1.6.0是在class Meta使用
template="xxx"
,最新版是template_name="xxx"
。 -
传递表类型数据给模板时,最好使用table类型的数据,因为queryset不能排序和分页。
-
获取分页的数据,可以使用table对象的paginator属性。
参考
https://django-tables2.readthedocs.io/en/stable/pages/tutorial.html
https://blog.csdn.net/qq_30252319/article/details/52094310