如何将Python生成的数据发送到jQuery数据表渲染

3 投票
2 回答
8961 浏览
提问于 2025-04-16 15:27

A] 问题总结:

在网页上使用jquery datatable(http://www.datatables.net/),想把从python生成的数据发送到javascript,这样就可以在表格中显示。如果有人能提供一个示例实现或者一个入门链接,那就太好了。

B] 模型结构:

模型之间的层级关系如下:

UserReportecCountry(一个)到 UserReportedCity(多个)

UserReportedCity(一个)到 UserReportedStatus(多个)

class UserReportedCountry(db.Model):
  country_name = db.StringProperty( required=True,
                          choices=['Afghanistan','Aring land Islands']
                         )

class UserReportedCity(db.Model):
  country = db.ReferenceProperty(UserReportedCountry, collection_name='cities')
  city_name = db.StringProperty(required=True)   

class UserReportedStatus(db.Model):
  city = db.ReferenceProperty(UserReportedCity, collection_name='statuses')
  status = db.BooleanProperty(required=True)
  date_time = db.DateTimeProperty(auto_now_add=True)

C] HTML代码摘录

这段HTML代码包含了jquery和datatable的javascript库。datatable的javascript库被配置为允许多列排序。

<!--importing javascript and css files -->
<style type="text/css">@import "/media/css/demo_table.css";</style>  
<script type="text/javascript" language="javascript" src="/media/js/jquery.js"></script>
<script type="text/javascript" src="/media/js/jquery.dataTables.js"></script>

<!-- Configuring the datatable javascript library to allow multicolumn sorting -->
<script type="text/javascript">
    /* Define two custom functions (asc and desc) for string sorting */
    jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
        return ((x < y) ? -1 : ((x > y) ?  1 : 0));
    };

    jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
        return ((x < y) ?  1 : ((x > y) ? -1 : 0));
    };

    $(document).ready(function() {
    /* Build the DataTable with third column using our custom sort functions */
    // #user_reported_data_table is the name of the table which is used to display the data reported by the users
    $('#user_reported_data_table').dataTable( {
        "aaSorting": [ [0,'asc'], [1,'asc'] ],
        "aoColumns": [
            null,
            null,
            { "sType": 'string-case' },
            null
        ]
    } );
} );
</script>

<!-- Table containing the data to be printed--> 
<div id="userReportedData">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="user_reported_data_table">
    <thead>
        <tr>
            <th>Country</th>
            <th>City</th>
            <th>Status</th>
            <th>Reported at</th>
        </tr>
    </thead>

    <tbody>
        <tr class="gradeA">
            <td>United Status</td>
            <td>Boston</td>
            <td>Up</td>
            <td>5 minutes back</td>
        </tr>
    </tbody>
</table>    

C] python代码摘录:

这段代码负责查询数据,把数据放进一个“模板”里,然后发送到HTML页面(当然现在还不能正常工作 :( )

__TEMPLATE_ALL_DATA_FROM_DATABASE = 'all_data_from_database'
def get(self): 
  template_values = {
        self.__TEMPLATE_ALL_DATA_FROM_DATABASE: self.get_data_reported_by_users()
    }

    self.response.out.write(template.render(self.__MAIN_HTML_PAGE, template_values))

def get_data_reported_by_users(self):
    return db.GqlQuery("SELECT * FROM UserReportedCountry ORDER BY country_name ASC")         

D] 使用的技术:

1] Jquery

2] Jquery datatable

3] Google app engine

4] Python

5] Django。

谢谢你的阅读。

[EDIT#1]

根据@Mark的回复编写的代码

尝试了以下内容

<!-- script snippet to setup the properties of the datatable(table which will contain site status    reported by the users) -->
<script type="text/javascript">
    /* Define two custom functions (asc and desc) for string sorting */
    jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
        return ((x < y) ? -1 : ((x > y) ?  1 : 0));
    };

    jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
        return ((x < y) ?  1 : ((x > y) ? -1 : 0));
    };

    $(document).ready(function() {
    /* Build the DataTable with third column using our custom sort functions */
    // #user_reported_data_table is the name of the table which is used to display the data reported by the users
    $('#user_reported_data_table').dataTable( {
        "aaSorting": [ [0,'asc'], [1,'asc'] ],
        "aoColumns": [
            null,
            null,
            { "sType": 'string-case' },
            null
        ],
        /* enabling serverside processing, specifying that the datasource for this will come from  
           file ajaxsource , function populate_world_wide_data
        */
        "bProcessing": true,
        "bServerSide": true,
        "sAjaxSource": "/ajaxsource/populate_world_wide_data"
    } );
} );
</script>

<div id="userReportedData">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="user_reported_data_table">
    <thead>
        <tr>
            <th>Country</th>
            <th>City</th>
            <th>Status</th>
            <th>Reported at</th>
        </tr>
    </thead>
    <tbody>

    </tbody>
</table>    

Python代码,文件名是ajaxsource.py

from django.utils import simplejson
from google.appengine.ext import db

def populate_world_wide_data(self,request):
    my_data_object = db.GqlQuery("SELECT * FROM UserReportedCountry ORDER BY country_name ASC") 
    json_object = simplejson.dumps(my_data_object)        
    self.response.out.write( json_object, mimetype='application/javascript')

不过这只在表格上显示了“处理中”。

有几个问题,datatable怎么知道在哪里打印国家,在哪里打印城市和状态呢?

[EDIT#2] 根据@Abdul Kader的回复编写的代码

<script type="text/javascript" src="/media/js/jquery.dataTables.js"></script>

<!-- script snippet to setup the properties of the datatable(table which will contain site status reported by the users) -->
<script type="text/javascript">
    /* Define two custom functions (asc and desc) for string sorting */
    jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
        return ((x < y) ? -1 : ((x > y) ?  1 : 0));
    };

    jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
        return ((x < y) ?  1 : ((x > y) ? -1 : 0));
    };

    $(document).ready(function() {
    /* Build the DataTable with third column using our custom sort functions */
    // #user_reported_data_table is the name of the table which is used to display the data reported by the users
    $('#user_reported_data_table').dataTable( {
        "aaSorting": [ [0,'asc'], [1,'asc'] ],
        "aoColumns": [
            null,
            null,
            { "sType": 'string-case' },
            null
        ]
    } );
} );
</script>


<!-- Table containing the data to be printed--> 
<div id="userReportedData">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="user_reported_data_table">
    <thead>
        <tr>
            <th>Country</th>
            <th>City</th>
            <th>Status</th>
            <th>Reported at</th>
        </tr>
    </thead>

   <tbody>
    <tr class="gradeA">
         {% for country in all_data_from_database %}
         <td>{{country}}</td>
         {%endfor%}
    </tr>
    </tbody>
</table>  

Python代码 --

__TEMPLATE_ALL_DATA_FROM_DATABASE = 'all_data_from_database'

def get(self): 
    template_values = {
        self.__TEMPLATE_ALL_DATA_FROM_DATABASE: self.get_data_reported_by_users()
    }

    #rendering the html page and passing the template_values
    self.response.out.write(template.render(self.__MAIN_HTML_PAGE, template_values))

def get_data_reported_by_users(self):
    return db.GqlQuery("SELECT * FROM UserReportedCountry ORDER BY country_name ASC") 

在HTML页面上打印的项目:

enter image description here

[EDIT#3] 有效的编辑。

我稍微修改了@Abdul Kader给出的解决方案,以下内容有效

HTML代码:

<!-- Table containing the data to be printed--> 
<div id="userReportedData">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="user_reported_data_table">
    <thead>
        <tr>
            <th>Country</th>
            <th>City</th>
            <th>Status</th>
            <th>Reported at</th>
        </tr>
    </thead>

   <tbody>

    {% for country in countries %}
        {%for city in country.cities %}
            {%for status in city.statuses %}
                <tr class="gradeA">
                    <td>{{country.country_name}}</td>
                    <td>{{city.city_name}}</td>
                    <td>{{status.status}}</td>
                    <td>{{status.date_time }}</td>
                </tr>
            {%endfor%}  
        {%endfor%}      
    {%endfor%}

    </tbody>
</table>  

Python代码:

def get(self):

   __TEMPLATE_ALL_DATA_FROM_DATABASE = 'countries'

    country_query = UserReportedCountry.all().order('country_name')
    country = country_query.fetch(10)

    template_values = {
        self.__TEMPLATE_ALL_DATA_FROM_DATABASE: country
    }

    self.response.out.write(template.render(self.__MAIN_HTML_PAGE, template_values))

增强请求:我认为这是一种非常基础的做法,可能还有更优雅的解决方案,可以涉及一些ajax。如果有人有使用python的datatables的示例或开源项目,请告诉我。

代码审查请求:能否请大家审查一下我写的代码,看看我是否犯了错误,或者有什么可以改进的地方,或者更高效的做法。

2 个回答

2

在DataTables的文档中,他们展示了一个从“服务器端”返回数据的例子。在这个例子中,他们在服务器上使用的是PHP,但返回数据的方式是通过JSON编码。其实用Python也能很简单地做到这一点。

编辑

关键在于数据是如何从服务器返回的:

$(document).ready(function() {
    $('#example').dataTable( {
        "bProcessing": true,
        "bServerSide": true,
        "sAjaxSource": "url/to/json/returning/python"
    } );
} );

在上面的JavaScript代码中,它会直接调用Python的Django视图,并期待得到一个JSON格式的响应。

Django视图大概是这样的(我不是Django用户,所以可能不太准确):

from django.utils import simplejson

def ajax_example(request):
    ## do your processing
    ## your return data should be a python object
    return HttpResponse(simplejson.dumps(my_data_object), mimetype='application/javascript')
2

你只需要像平常一样从数据存储中创建表格。插件会处理剩下的事情。

模型

class UserReportedCountry(db.Model):
  country_name = db.StringProperty( required=True,
                          choices=['Afghanistan','Aring land Islands']
                         )

class UserReportedCity(db.Model):
  country = db.ReferenceProperty(UserReportedCountry, collection_name='cities')
  city_name = db.StringProperty(required=True)   

class UserReportedStatus(db.Model):
  city = db.ReferenceProperty(UserReportedCity, collection_name='statuses')
  status = db.BooleanProperty(required=True)
  date_time = db.DateTimeProperty(auto_now_add=True)

Python

class MainPage(webapp.RequestHandler):
    def get(self):
        User_country=UserReportedCountry.all().fetch(1000)
        return self.response.out.write(template.render('#pathtohtml','{'user_c':User_country}))

HTML

<!--importing javascript and css files -->
<style type="text/css">@import "/media/css/demo_table.css";</style>  
<script type="text/javascript" language="javascript" src="/media/js/jquery.js"></script>
<script type="text/javascript" src="/media/js/jquery.dataTables.js"></script>

<!-- Configuring the datatable javascript library to allow multicolumn sorting -->
<script type="text/javascript">
    /* Define two custom functions (asc and desc) for string sorting */
    jQuery.fn.dataTableExt.oSort['string-case-asc']  = function(x,y) {
        return ((x < y) ? -1 : ((x > y) ?  1 : 0));
    };

    jQuery.fn.dataTableExt.oSort['string-case-desc'] = function(x,y) {
        return ((x < y) ?  1 : ((x > y) ? -1 : 0));
    };

    $(document).ready(function() {
    /* Build the DataTable with third column using our custom sort functions */
    // #user_reported_data_table is the name of the table which is used to display the data reported by the users
    $('#user_reported_data_table').dataTable( {
        "aaSorting": [ [0,'asc'], [1,'asc'] ],
        "aoColumns": [
            null,
            null,
            { "sType": 'string-case' },
            null
        ]
    } );
} );
</script>

<!-- Table containing the data to be printed--> 
<div id="userReportedData">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="user_reported_data_table">
    <thead>
        <tr>
            <th>Country</th>
            <th>City</th>
            <th>Status</th>
            <th>Reported at</th>
        </tr>
    </thead>

    <tbody>
        <tr class="gradeA">
             {% for country in user_c %}
             <td>{{country}}</td>
             {%endfor%}
        </tr>
    </tbody>
</table>  

撰写回答