Как отправить данные, сгенерированные из python, в jquery datatable для рендеринга

#jquery #python #google-app-engine #datatable

#jquery #python #google-app-engine #datatable

Вопрос:

A] Краткое описание проблемы:

Используя jquery datatable (http://www.datatables.net) на html-странице требуется отправить данные, сгенерированные запросом из python в javascript, чтобы их можно было распечатать в таблице. Если кто-нибудь может предоставить пример реализации для этого или начальную ссылку, это было бы потрясающе.

B] Структура моделей:

Иерархическая взаимосвязь между моделями выглядит следующим образом:

Userreportecountry (one) в UserReportedCity (many)

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. Библиотека javascript datatable настроена так, чтобы разрешать сортировку по нескольким столбцам.

 <!--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.

thank you for reading.

[EDIT#1]

Code based on the response given by @Mark

Tried the following

 <!-- 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

из django.utils импортировать simplejson из Google.appengine.ext импортировать базу данных

 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 узнает, где печатать страну, где печатать город и статус?

[РЕДАКТИРОВАТЬ# 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-странице:

введите описание изображения здесь

[ПРАВКА # 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, пожалуйста, дайте мне знать.

Запрос на проверку кода: Может ли кто-нибудь, пожалуйста, просмотреть код, который я сделал, и сообщить мне, если я делаю ошибку или что-то, что можно сделать лучше или более эффективным способом.

Комментарии:

1. @Ник Джонсон, спасибо за ваш ответ. Я попытался напрямую отправить данные, сгенерированные из запроса, на html-страницу, но это не сработало. Поскольку это, по-видимому, распространенная проблема, я надеялся на библиотеку, которая может передавать данные, чтобы они могли быть прочитаны кодом javascript на стороне клиента. Я уверен, что написание моей собственной пользовательской библиотеки не является правильным решением, и поэтому я опубликовал вопрос.

2. «Прямая отправка» как? В ответ на что? Документы datatable предоставляют множество примеров — основное использование — просто сгенерировать обычную HTML-таблицу. Если вы хотите добавить данные после загрузки страницы, это тоже задокументировано, как демонстрирует @Mark.

3. Я думаю, в качестве первого шага вы должны убедиться, что ваша таблица отображается правильно. Похоже, это суть вашей проблемы. Как насчет строки, содержащей Бостон / США … это просто пример или реальный результат вашего запроса? Если вы правильно отобразите свою таблицу, я бы начал с минимальных параметров для таблиц данных ( datatables.net/examples/basic_init/zero_config.html ) и добавить более сложные параметры позже.

Ответ №1:

Вам нужно просто создать таблицу из хранилища данных, как вы обычно делаете. Плагин позаботится обо всем остальном. Модели

 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>  
  

Комментарии:

1. @Abdul Kader, спасибо за ваш ответ. Извините за поздний ответ, я собираюсь сначала попробовать ответ, данный @Mark в комментарии выше, и проверить, сработает ли он. Я также рассмотрю ваш ответ и посмотрю, применим ли он к сценарию, с которым я сталкиваюсь. Еще раз спасибо за ваш ответ.

2. @Abdul Kader, я попробовал код, основанный на вашем ответе. Проблем с интерпретацией не было, но код не печатает никаких записей в html datatable. Код и результирующая таблица данных размещены в разделе «РЕДАКТИРОВАТЬ # 2» моего основного поста.

3. @bhavesh убедитесь, что ваша all_data_from_database извлекает записи. импортируйте протоколирование и выполните некоторые logging.info () чтобы определить, извлекает ли этот actullay запись. Также убедитесь, что тип записи уже существует в хранилище данных

4. @Абдул Кадер, ты устроил мне вечер!!!. Я немного изменил решение, данное вами, и в «EDIT # 3» есть решение, которое сработало. Проблема заключалась в том, что мы пытались напечатать объект «country», требовалось получить доступ к «country_name» и другим полям для объекта. Я все еще считаю, что это неэффективный механизм для выполнения того, что я хочу сделать. Не могли бы вы, пожалуйста, просмотреть мой код и оставить отзыв, основанный на вашем опыте. Еще раз большое спасибо, чувак, твой ответ был высоко оценен.

5. @bhavesh я не думаю, что вам нужны три цикла for там. Одного цикла for должно быть достаточно. Попробуйте выяснить, как именно рендерится система шаблонов.

Ответ №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')
  

Комментарии:

1. мне трудно понять php-код по вашей ссылке. Я потрачу еще немного времени, но есть ли более простой способ сделать это?

2. @bhavesh, если вы можете обойти PHP-ность примера, это на самом деле довольно просто. Смотрите правки выше.

3. извините за поздний ответ, у меня не было доступа в Интернет последние пару дней. Спасибо, что объяснили, как этого можно достичь, я собираюсь попробовать сделать это сегодня вечером (ETA 8: 00 вечера по восточному времени) и предоставлю результаты.

4. как и было обещано, я попробовал ответ, который вы дали, но не смог заставить его работать. Я уверен, что совершаю ошибку новичка. Код, который я пробовал, размещен в разделе «[РЕДАКТИРОВАТЬ # 1]» моего основного поста.

5. Я попробовал механизм, предоставленный @Abdul Kader, и добился прогресса в плане того, чтобы заставить его работать. Я считаю, что код, который я использую, неэффективен, и мог бы быть лучший механизм для достижения того, что я хочу сделать. Не могли бы вы, пожалуйста, сделать обзор кода «EDIT # 3» и сообщить мне, если я допускаю какие-либо ошибки. Еще раз спасибо Марку за то, что прочитал мою проблему и предоставил ответ.