From 9d07e8a26657542c98535abb7812d83a98839918 Mon Sep 17 00:00:00 2001 From: Alvin Li Date: Sun, 18 Aug 2013 00:52:06 +0800 Subject: * improved 'indicator.views.follow_indicator()', renamed to 'indicator_fanduf()' due to name conflict * finished 'search' function for page indicator NewDeleteIndex.html * added 'apps/utils/search_tools.py': some tools to process search results * renamed 'sciblog/templatetags/tools.py' to 'get_range.py' * added 'format_data()' to indicator.tools': to format data of record/confine, make it properly display in html page; * 'indicator/javascripts/new_delete_index.js': added global 'var added_indexes_id' to track the already added indexes * added 'indicator/templatetags/divisible_by.py' filter to check if a number can be extactly divide by another number; * fixed the 'index_card_fir/index_card_sec' problem of 'act_card_container' of page 'SheetDefault.html' * indicator/static/css/new_delete_index.css: added 'index_search_error' and 'index_error' * fixed 'unit.dump' problems in 'indicator.models' * 'indicator.tools': o added 'RI_TYPES', 'RI_WEIGHTS' o added 'type' in the return value of 'calc_indicator_weight()' and 'recommend_indicator()' * added field 'followedHistories' in 'indicator.models.UserIndicator' * moved 'follow_indicator()' and 'unfollow_indicator()' from 'indicator.views' to 'indicator.tools' TODO: * highcharts: draw chart for indicator records; * add/edit data, and submit (page format design) * followed indicator submit buttion --- .../apps/indicator/fixtures/initial_data.json | 203 +++++++++--- 97suifangqa/apps/indicator/models.py | 30 +- 97suifangqa/apps/indicator/search_indexes.py | 4 + .../apps/indicator/static/css/new_delete_index.css | 12 + .../apps/indicator/static/css/sheet_default.css | 9 +- .../static/javascripts/delete_card_tip.js | 26 +- .../apps/indicator/static/javascripts/load_card.js | 107 +++--- .../static/javascripts/new_delete_index.js | 26 +- .../templates/indicator/NewDeleteIndex.html | 110 ++----- .../templates/indicator/SheetDefault.html | 361 ++++++++++----------- .../apps/indicator/templates/indicator/index.html | 2 +- .../templates/indicator/popup/DeleteCardTip.html | 4 +- .../apps/indicator/templatetags/divisible_by.py | 30 ++ 97suifangqa/apps/indicator/tools.py | 204 ++++++++++-- 97suifangqa/apps/indicator/urls.py | 12 +- 97suifangqa/apps/indicator/views.py | 302 +++++++++++++---- 97suifangqa/apps/info/fixtures/initial_data.json | 156 ++++----- .../apps/sciblog/fixtures/initial_data.json | 4 +- 97suifangqa/apps/sciblog/templatetags/get_range.py | 7 + 97suifangqa/apps/sciblog/templatetags/tools.py | 7 - 97suifangqa/apps/utils/search_tools.py | 28 ++ 97suifangqa/fixtures/initial_data.json | 20 +- 97suifangqa/isuifangqa.db | Bin 392192 -> 397312 bytes 97suifangqa/templates/sciblog/blog_list.html | 2 +- 24 files changed, 1094 insertions(+), 572 deletions(-) create mode 100644 97suifangqa/apps/indicator/templatetags/divisible_by.py create mode 100644 97suifangqa/apps/sciblog/templatetags/get_range.py delete mode 100644 97suifangqa/apps/sciblog/templatetags/tools.py create mode 100644 97suifangqa/apps/utils/search_tools.py diff --git a/97suifangqa/apps/indicator/fixtures/initial_data.json b/97suifangqa/apps/indicator/fixtures/initial_data.json index 25d6c73..07aeaaa 100644 --- a/97suifangqa/apps/indicator/fixtures/initial_data.json +++ b/97suifangqa/apps/indicator/fixtures/initial_data.json @@ -1,24 +1,79 @@ [ { - "pk": 1, + "pk": 4, + "model": "indicator.indicatorcategory", + "fields": { + "pinyin": "gan-chuan-ci", + "englishName": "Liver Puncture", + "addByUser": 1, + "name": "\u809d\u7a7f\u523a", + "description": "\u809d\u7a7f\u523a" + } + }, + { + "pk": 3, + "model": "indicator.indicatorcategory", + "fields": { + "pinyin": "gan-gong-neng", + "englishName": "Liver Function", + "addByUser": 1, + "name": "\u809d\u529f\u80fd", + "description": "\u809d\u529f\u80fd" + } + }, + { + "pk": 5, + "model": "indicator.indicatorcategory", + "fields": { + "pinyin": "lei-bie-5", + "englishName": "category5", + "addByUser": 1, + "name": "\u7c7b\u522b5", + "description": "\u7c7b\u522b5\r\n\u6d4b\u8bd5" + } + }, + { + "pk": 6, "model": "indicator.indicatorcategory", "fields": { - "pinyin": "lei-bie-1", - "englishName": "category1", + "pinyin": "lei-bie-6", + "englishName": "category6", "addByUser": 1, - "name": "\u7c7b\u522b1", - "description": "\u6307\u6807\u7c7b\u522b1\r\n\r\n\u4fee\u65391\uff08\u6d4b\u8bd5\uff09" + "name": "\u7c7b\u522b6", + "description": "\u7c7b\u522b6\r\n\r\n\u6d4b\u8bd5" + } + }, + { + "pk": 7, + "model": "indicator.indicatorcategory", + "fields": { + "pinyin": "lei-bie-7", + "englishName": "category7", + "addByUser": 1, + "name": "\u7c7b\u522b7", + "description": "\u7c7b\u522b7\r\n\r\n\u6d4b\u8bd5" } }, { "pk": 2, "model": "indicator.indicatorcategory", "fields": { - "pinyin": "lei-bie-2", - "englishName": "category2", + "pinyin": "liang-dui-ban", + "englishName": "TODO", "addByUser": 1, - "name": "\u7c7b\u522b2", - "description": "\u7c7b\u522b2\r\n\r\nadd_edit_category() \u6dfb\u52a0" + "name": "\u4e24\u5bf9\u534a", + "description": "\u4e59\u809d\u4e24\u5bf9\u534a" + } + }, + { + "pk": 1, + "model": "indicator.indicatorcategory", + "fields": { + "pinyin": "xie-chang-gui", + "englishName": "Blood Routine", + "addByUser": 1, + "name": "\u8840\u5e38\u89c4", + "description": "\u8840\u5e38\u89c4" } }, { @@ -27,14 +82,30 @@ "fields": { "addByUser": 1, "name": "\u6d4b\u8bd51", - "dataType": "FL", + "dataType": "PM", "pinyin": "ce-shi-1", "helpText": "\u5e2e\u52a9 help", "englishName": "test1", + "categories": [ + 2 + ], + "description": "forms \u6d4b\u8bd51\r\npm type" + } + }, + { + "pk": 1, + "model": "indicator.indicator", + "fields": { + "addByUser": 1, + "name": "\u5b9a1", + "dataType": "FL", + "pinyin": "ding-1", + "helpText": "\u6d6e\u70b9\u578b", + "englishName": "indicator1", "categories": [ 1 ], - "description": "forms \u6d4b\u8bd51" + "description": "\u5b9a\u503c1\r\n\r\n\u6d6e\u70b9\u578b\u6570\u636e" } }, { @@ -42,12 +113,13 @@ "model": "indicator.indicator", "fields": { "addByUser": 1, - "name": "\u5b9a\u503c1", + "name": "\u5b9a\u503c2", "dataType": "FL", - "pinyin": "ding-zhi-1", + "pinyin": "ding-zhi-2", "helpText": "\u6d6e\u70b9\u5b9a\u503c", - "englishName": "float1", + "englishName": "float2", "categories": [ + 2, 1 ], "description": "float type" @@ -71,28 +143,24 @@ }, { "pk": 1, - "model": "indicator.indicator", + "model": "indicator.userindicator", "fields": { - "addByUser": 1, - "name": "\u6307\u68071", - "dataType": "FL", - "pinyin": "zhi-biao-1", - "helpText": "\u6d6e\u70b9\u578b", - "englishName": "indicator1", - "categories": [ - 1 + "followedIndicators": [ + 3, + 1, + 2 ], - "description": "\u6307\u68071\r\n\r\n\u6d6e\u70b9\u578b\u6570\u636e" + "followedHistories": [], + "user": 1 } }, { - "pk": 1, + "pk": 2, "model": "indicator.userindicator", "fields": { - "followedIndicators": [ - 4 - ], - "user": 1 + "followedIndicators": [], + "followedHistories": [], + "user": 2 } }, { @@ -101,8 +169,8 @@ "fields": { "indicator": 1, "notes": "\u6307\u68071\r\n\u7b2c1\u6761\u8bb0\u5f55", - "created_at": "2013-08-05T15:48:00.035", - "updated_at": "2013-08-05T15:50:00.326", + "created_at": "2013-08-05T15:48:00.035Z", + "updated_at": "2013-08-05T15:50:00.326Z", "value": "250", "val_min": null, "user": 1, @@ -116,23 +184,39 @@ "model": "indicator.indicatorrecord", "fields": { "indicator": 1, - "notes": "test\r\n\u8bb0\u5f55", - "created_at": "2013-08-09T10:53:15.927", - "updated_at": "2013-08-10T00:30:09.336", + "notes": "\r\n\u8bb0\u5f55", + "created_at": "2013-08-09T10:53:15.927Z", + "updated_at": "2013-08-16T16:23:33.798Z", "value": "50", "val_min": null, - "user": 2, + "user": 1, "date": "2013-08-09", "val_max": null, "unit": 1 } }, + { + "pk": 3, + "model": "indicator.indicatorrecord", + "fields": { + "indicator": 3, + "notes": "pm type\r\nrecord 1", + "created_at": "2013-08-16T16:07:00.547Z", + "updated_at": "2013-08-16T16:07:00.547Z", + "value": "+", + "val_min": null, + "user": 1, + "date": "2013-08-17", + "val_max": null, + "unit": null + } + }, { "pk": 1, "model": "indicator.recordhistory", "fields": { "val_min_bak": null, - "created_at": "2013-08-05T16:07:01.832", + "created_at": "2013-08-05T16:07:01.832Z", "indicatorRecord": 1, "reason": "\u6d4b\u8bd5\r\nadmin\u754c\u9762\u76f4\u63a5\u4fee\u6539", "unit_bak": 1, @@ -147,7 +231,7 @@ "model": "indicator.recordhistory", "fields": { "val_min_bak": null, - "created_at": "2013-08-10T11:40:23.170", + "created_at": "2013-08-10T11:40:23.170Z", "indicatorRecord": 1, "reason": "\u6d4b\u8bd5\u4fee\u6539", "unit_bak": 1, @@ -228,15 +312,30 @@ "pk": 2, "model": "indicator.innateconfine", "fields": { - "math_max": 800.0, + "math_max": 80000.0, "indicator": 2, - "human_max": 500.0, + "human_max": 50000.0, "description": "\u6307\u6807\r\n\r\n\u6570\u636e\u7c7b\u578b\uff1a\u8303\u56f4\u578b\r\n\r\n\u6570\u636e\u8303\u56f4", "val_norm": "", "addByUser": 1, - "human_min": 50.0, + "human_min": 10000.0, "unit": 3, - "math_min": 0.0 + "math_min": 5000.0 + } + }, + { + "pk": 3, + "model": "indicator.innateconfine", + "fields": { + "math_max": null, + "indicator": 3, + "human_max": null, + "description": "pm type", + "val_norm": "+", + "addByUser": 1, + "human_min": null, + "unit": null, + "math_min": null } }, { @@ -245,8 +344,8 @@ "fields": { "indicator": 1, "weight": 5.9, - "created_at": "2013-08-10T22:40:00.035", - "updated_at": "2013-08-10T22:40:00.326", + "created_at": "2013-08-10T22:40:00.035Z", + "updated_at": "2013-08-10T22:40:00.326Z", "blog": null, "annotation": 2, "objectType": "AN" @@ -258,8 +357,8 @@ "fields": { "indicator": 1, "weight": 8.0, - "created_at": "2013-08-11T00:56:08.080", - "updated_at": "2013-08-11T00:56:08.080", + "created_at": "2013-08-11T00:56:08.080Z", + "updated_at": "2013-08-11T00:56:08.080Z", "blog": null, "annotation": 1, "objectType": "AN" @@ -271,8 +370,8 @@ "fields": { "indicator": 2, "weight": 8.3, - "created_at": "2013-08-10T22:50:00.035", - "updated_at": "2013-08-10T22:50:00.326", + "created_at": "2013-08-10T22:50:00.035Z", + "updated_at": "2013-08-10T22:50:00.326Z", "blog": 3, "annotation": null, "objectType": "BL" @@ -284,8 +383,8 @@ "fields": { "indicator": 1, "weight": 4.0, - "created_at": "2013-08-11T00:56:49.463", - "updated_at": "2013-08-11T00:56:49.463", + "created_at": "2013-08-11T00:56:49.463Z", + "updated_at": "2013-08-11T00:56:49.463Z", "blog": 1, "annotation": null, "objectType": "BL" @@ -297,11 +396,11 @@ "fields": { "indicator": 1, "weight": 6.0, - "created_at": "2013-08-11T00:57:23.067", - "updated_at": "2013-08-11T00:57:23.067", + "created_at": "2013-08-11T00:57:23.067Z", + "updated_at": "2013-08-11T00:57:23.067Z", "blog": 3, "annotation": null, "objectType": "BL" } } -] \ No newline at end of file +] diff --git a/97suifangqa/apps/indicator/models.py b/97suifangqa/apps/indicator/models.py index 615398f..18c699c 100644 --- a/97suifangqa/apps/indicator/models.py +++ b/97suifangqa/apps/indicator/models.py @@ -247,7 +247,11 @@ class UserIndicator(models.Model): # {{{ related_name="user_indicator") followedIndicators = models.ManyToManyField(Indicator, verbose_name=u"关注的指标", - related_name="user_indicators", + related_name="followed_indicators", + null=True, blank=True) + followedHistories = models.ManyToManyField(Indicator, + verbose_name=u"历史关注指标", + related_name="followed_histories", null=True, blank=True) class Meta: @@ -658,6 +662,12 @@ class IndicatorRecord(models.Model): # {{{ # }}} def dump(self, **kwargs): + # check if the indicator needs unit + if self.unit: + unit_id = self.unit.id + else: + unit_id = None + # dump dump_data = { 'id': self.id, 'indicator_id': self.indicator.id, @@ -665,7 +675,7 @@ class IndicatorRecord(models.Model): # {{{ 'created_at': self.created_at.isoformat(), 'updated_at': self.updated_at.isoformat(), 'date': self.date.isoformat(), - 'unit_id': self.unit.id, + 'unit_id': unit_id, 'value': self.value, 'val_max': self.val_max, 'val_min': self.val_min, @@ -724,13 +734,19 @@ class RecordHistory(models.Model): # {{{ super(RecordHistory, self).save(**kwargs) def dump(self, **kwargs): + # check 'unit_bak' + if self.unit_bak: + unit_bak_id = self.unit_bak.id + else: + unit_bak_id = None + # dump dump_data = { 'id': self.id, 'indicatorRecord_id': self.indicatorRecord.id, 'created_at': self.created_at.isoformat(), 'reason': self.reason, 'date_bak': self.date_bak.isoformat(), - 'unit_bak_id': self.unit_bak.id, + 'unit_bak_id': unit_bak_id, 'value_bak': self.value_bak, 'val_max_bak': self.val_max_bak, 'val_min_bak': self.val_min_bak, @@ -930,10 +946,16 @@ class InnateConfine(models.Model): # {{{ # }}} def dump(self, **kwargs): + # check unit, if the indicator not need unit, then return {} + if self.unit: + unit_dump = self.unit.dump() + else: + unit_dump = {} + # dump dump_data = { 'id': self.id, 'indicator_id': self.indicator.id, - 'unit': self.unit.dump(), + 'unit': unit_dump, 'val_norm': self.val_norm, 'human_max': self.human_max, 'human_min': self.human_min, diff --git a/97suifangqa/apps/indicator/search_indexes.py b/97suifangqa/apps/indicator/search_indexes.py index 67d5723..f225b2c 100644 --- a/97suifangqa/apps/indicator/search_indexes.py +++ b/97suifangqa/apps/indicator/search_indexes.py @@ -12,6 +12,8 @@ class IndicatorCategoryIndex(indexes.SearchIndex, indexes.Indexable): search index for 'Indicator' """ text = indexes.CharField(document=True, use_template=True) + # pinyin: for ordering the search result + pinyin = indexes.CharField(model_attr='pinyin') addByUser = indexes.CharField(model_attr='addByUser') def get_model(self): @@ -31,6 +33,8 @@ class IndicatorIndex(indexes.SearchIndex, indexes.Indexable): search index for 'Indicator' """ text = indexes.CharField(document=True, use_template=True) + # pinyin: for ordering the search result + pinyin = indexes.CharField(model_attr='pinyin') addByUser = indexes.CharField(model_attr='addByUser') dataType = indexes.CharField(model_attr='dataType') categories_id = indexes.MultiValueField() diff --git a/97suifangqa/apps/indicator/static/css/new_delete_index.css b/97suifangqa/apps/indicator/static/css/new_delete_index.css index 0eb41d1..b5b161a 100644 --- a/97suifangqa/apps/indicator/static/css/new_delete_index.css +++ b/97suifangqa/apps/indicator/static/css/new_delete_index.css @@ -160,6 +160,18 @@ width: 185px; } +.index_search_error { + margin-top: 3px; +} +.index_search_error .index_error { + float: left; + font-size: 14px; + height: 20px; + line-height: 20px; + color: #4A4A4A; + font-weight: bold; +} + .all_condition .index_all_title { font-weight: bold; font-size: 19px; diff --git a/97suifangqa/apps/indicator/static/css/sheet_default.css b/97suifangqa/apps/indicator/static/css/sheet_default.css index aca021c..15d1a98 100644 --- a/97suifangqa/apps/indicator/static/css/sheet_default.css +++ b/97suifangqa/apps/indicator/static/css/sheet_default.css @@ -153,6 +153,9 @@ .index_card .refer_range .refer_text { margin-right: 5px; } +.index_card .refer_range .refer_value { + margin-right: 5px; +} .index_card .edit_data, .index_card .editing_data { height: 25px; margin-top: 7px; @@ -216,6 +219,10 @@ margin-top: 1px; cursor: pointer; } +.index_card .editing_data .data_unit { + float: left; + margin-right: 8px; +} .index_card .editing_data .cancel_edit_icon { float: right; background:url(../images/cancel_edit.png) no-repeat; @@ -356,4 +363,4 @@ } .move_div_2_left { float: left; -} \ No newline at end of file +} diff --git a/97suifangqa/apps/indicator/static/javascripts/delete_card_tip.js b/97suifangqa/apps/indicator/static/javascripts/delete_card_tip.js index 099a216..9365d46 100644 --- a/97suifangqa/apps/indicator/static/javascripts/delete_card_tip.js +++ b/97suifangqa/apps/indicator/static/javascripts/delete_card_tip.js @@ -1,4 +1,7 @@ +// global js var: card_2_delete_id (type: string) + $(document).ready(function(){ +// console.log(parent.card_2_delete_id); //要取消关注的 卡片id 的获取方法 //点大叉、继续关注按钮,关闭弹层页面 $(".delete_card_tip_close, .action_confirm_ignore").bind("click", function(){ parent.TB_remove(); @@ -7,12 +10,23 @@ $(document).ready(function(){ //取消关注,关闭弹层页面 $(".action_confirm_cancel").bind("click", function(){ - //TODO - //底层数据层取消关注(ajax) - //console.log(parent.card_2_delete_id); //要取消关注的 卡片id 的获取方法 + // ajax process to unfollow the indicator + // indicator_id -> parseInt(parent.card_2_delete_id) + // 底层数据层取消关注(ajax) + var date = new Date(); + var time = date.getTime(); + $.ajax({ + type: 'get', + url: parent.indicator_url + 'ajax/unfollow_indicator', + data: 'indicator_id='+parent.card_2_delete_id+'&time='+time, + success: function(data) { + if (data == 'success') { + parent.delete_card(); + parent.TB_remove(); + } + }, + }); - parent.delete_card(); - parent.TB_remove(); return false; }); -}); \ No newline at end of file +}); diff --git a/97suifangqa/apps/indicator/static/javascripts/load_card.js b/97suifangqa/apps/indicator/static/javascripts/load_card.js index 4db48a4..160273b 100644 --- a/97suifangqa/apps/indicator/static/javascripts/load_card.js +++ b/97suifangqa/apps/indicator/static/javascripts/load_card.js @@ -1,26 +1,61 @@ var detail_chart; -$(document).ready(function(){ - var startDate = '2013-07-13'; - startDate = new Date(startDate.replace(/-/g,"/")); - var start_date_UTC_time = startDate.getTime() - startDate.getTimezoneOffset() * 60 * 1000; - var chart3 = new Highcharts.Chart({ + +// set global options for hightcharts {{{ +$(function() { + Highcharts.setOptions ({ chart: { - renderTo: 'chart_3', type: 'area', marginLeft: 15, height: 223, spacingTop: 10, - spacingBottom: 0, - overflow: false, - zIndex: 5 + spacingBottom: 0 + //overflow: false, + //zIndex: 5 }, + colors: ['#31B6AD'], credits: { enabled: false }, + legend: { + enabled: false + }, + plotOptions: { + series: { + fillOpacity: 0.12, + lineWidth: 1, + marker: { + enabled: true, //false false的时候就不会突出显示点 + lineColor: '#31B6AD', + lineWidth: 1, + radius: 3, // 点的大小 + fillColor: '#FFFFFF' // 设置点中间填充的颜色 + }, + shadow: false + //threshold: null + } + }, + //series: [{ + // data: [6.0, 5.9, 5.5, 4.5, 6.2, 6.5, 5.2, 6.0, + // 5.9, 5.5, 4.5, 6.2, 6.5, 5.2, 6.0, 5.9, + // 5.5, 4.5, 6.2, 6.5], + // pointStart: start_date_UTC_time, + // pointInterval: 1 * 24 * 3600 * 1000 // one day + //}], title: { - text: ' ' + text: null + }, + tooltip: { + //formatter: function() { + // return '' + Highcharts.dateFormat('%b %e', this.x) + '' +'
' + '' + this.y + 'mmol/L' + '' + '
' + 'click for more info'; + //}, + // positioner: function (boxWidth, boxHeight, point) { + // return { x: point.plotX+80, y: point.plotY-20 }; + // }, + style: { + padding: '7px' + }, + borderColor: '#EAEAEA' }, - colors: ['#31B6AD'], xAxis: { type: 'datetime', dateTimeLabelFormats: { @@ -34,13 +69,13 @@ $(document).ready(function(){ step: 2, maxStaggerLines: 1 }, - tickInterval: (4 * 24 * 3600 * 1000), + tickInterval: (4 * 24 * 3600 * 1000), // 4 days tickColor: '#FFFFFF' }, yAxis: { - title: { - text: '' - }, + //title: { + // text: '' + //}, allowDecimals: false, endOnTick: false, tickInterval: 1, @@ -50,36 +85,31 @@ $(document).ready(function(){ gridLineWidth: 1, minPadding: 0.3, maxPadding: 1.2 + } + }); +}); +// }}} + +$(document).ready(function(){ + var startDate = '2013-07-13'; + startDate = new Date(startDate.replace(/-/g,"/")); + var start_date_UTC_time = startDate.getTime() - startDate.getTimezoneOffset() * 60 * 1000; + var chart3 = new Highcharts.Chart({ + chart: { + renderTo: 'chart_3' }, - legend: { - enabled: false + yAxis: { + title: { + text: '' + } }, tooltip: { formatter: function() { return '' + Highcharts.dateFormat('%b %e', this.x) + '' +'
' + '' + this.y + 'mmol/L' + '' + '
' + 'click for more info'; - }, + } // positioner: function (boxWidth, boxHeight, point) { // return { x: point.plotX+80, y: point.plotY-20 }; // }, - style: { - padding: '7px' - }, - borderColor: '#EAEAEA' - }, - plotOptions: { - series: { - marker: { - enabled: true, //false false的时候就不会突出显示点 - lineColor: '#31B6AD', - lineWidth: 1, - radius: 3, // 点的大小 - fillColor: '#FFFFFF' // 设置点中间填充的颜色 - }, - fillOpacity: 0.12, - lineWidth: 1, - threshold: null, - shadow: false - } }, series: [{ data: [6.0, 5.9, 5.5, 4.5, 6.2, 6.5, 5.2, 6.0, 5.9, 5.5, 4.5, 6.2, 6.5, 5.2, 6.0, 5.9, 5.5, 4.5, 6.2, 6.5], @@ -254,7 +284,8 @@ function redraw_chart(detail_chart, start, end){ url: indicator_url + 'ajax/get_card_data_chart', data: 'card_detail_id='+card_detail_id+'&start='+start+'&end='+end+'&time='+time, dataType: 'json', - success: function(dataJson) { //每一天都要有数据,否则x轴刻度时间对不上 + success: function(dataJson) { + //每一天都要有数据,否则x轴刻度时间对不上 var startDateLogFormat = new Date(start.replace(/-/g,"/")); var start_date_log_UTC_time = startDateLogFormat.getTime() - startDateLogFormat.getTimezoneOffset() * 60 * 1000; var pointStart = start_date_log_UTC_time; diff --git a/97suifangqa/apps/indicator/static/javascripts/new_delete_index.js b/97suifangqa/apps/indicator/static/javascripts/new_delete_index.js index 2c05d7f..8beed99 100644 --- a/97suifangqa/apps/indicator/static/javascripts/new_delete_index.js +++ b/97suifangqa/apps/indicator/static/javascripts/new_delete_index.js @@ -1,3 +1,6 @@ +// track the indexes already added(/followed) +var added_indexes_id = new Array(); + $(document).ready(function(){ $("#search_btn").bind("click", function(){ var kw = $("#search_kw").val(); @@ -10,6 +13,11 @@ $(document).ready(function(){ $(".right>.index_line").each(function(){ classHover($(this), "minus"); }); + // save the "index_id's of added (type: string) + $(".right>.index_line").each(function(){ + var index_id = $(this).attr("index_id"); + added_indexes_id.push(index_id); + }); $(".add>.icon").live("click", function(){ var add_icon = $(this); var index_id = add_icon.closest(".index_line").attr("index_id"); @@ -21,12 +29,16 @@ $(document).ready(function(){ data: 'index_id='+index_id+'&act=add'+'&time='+time, success: function(data){ if(data == 'success'){ - var obj = add_icon.parent(); - var objClone = obj.clone(); - objClone.removeClass("add") - objClone.children(".index_category").remove(); - $(".right").append(objClone); - classHover(objClone, "minus"); + // check if the index exists? + if (added_indexes_id.indexOf(index_id) == -1) { + var obj = add_icon.parent(); + var objClone = obj.clone(); + objClone.removeClass("add") + objClone.children(".index_category").remove(); + $(".right").append(objClone); + classHover(objClone, "minus"); + added_indexes_id.push(index_id); + } } } }); @@ -45,6 +57,8 @@ $(document).ready(function(){ success: function(data){ var obj = minus_icon.parent(); obj.remove(); + rm_index = added_indexes_id.indexOf(index_id); + added_indexes_id.splice(rm_index, 1); } }); diff --git a/97suifangqa/apps/indicator/templates/indicator/NewDeleteIndex.html b/97suifangqa/apps/indicator/templates/indicator/NewDeleteIndex.html index c2a219a..f4e9a18 100644 --- a/97suifangqa/apps/indicator/templates/indicator/NewDeleteIndex.html +++ b/97suifangqa/apps/indicator/templates/indicator/NewDeleteIndex.html @@ -52,19 +52,8 @@
- - -
+ @@ -146,6 +135,7 @@
+ {% if page_condition == "category" %}
{% for ind in indicators %}
@@ -156,6 +146,7 @@
{% endfor %}
+ {% endif %} {# end: page_condition == "category" #}
@@ -164,36 +155,42 @@
搜索指标
-
仿真化验单
+
+ {% if page_condition == "search" %}
{# 'indicators': list made up by the dumps of indicator #} - {% for ind in indicators %} - -
-
{{ ind|dict_get:"name" }}
-
- {{ ind|dict_get:"categories_name"|first }} + {# check if search keyword empty & if search result empty #} + {% if search_kw_empty %} + {# search keyword empty #} +
+
您未输入搜索关键词
+
+
-
-
-
- {% endfor %} -
-
乙肝病毒S蛋白定量
-
血常规
-
-
-
-
-
乙肝病毒表面抗体
-
血常规
-
-
-
+ {% elif search_result_empty %} + {# search result empty #} +
+
未搜索到符合的结果
+
+
+
+ {% else %} + {% for ind in indicators %} +
+
{{ ind|dict_get:"name" }}
+ +
+
+
+ {% endfor %} + {% endif %}
+ {% endif %} {# end: page_condition == "search" #}
@@ -219,49 +216,6 @@
{% endfor %} - - {% comment %}{# vim: {{{ #} -
-
V-谷丙氨酰转氨酶
-
-
-
-
-
总胆红素
-
-
-
-
-
乙肝病毒表面抗原
-
-
-
-
-
乙肝病毒表面抗体
-
-
-
-
-
乙肝病毒e抗体
-
-
-
-
-
乙肝病毒核算定量(PCR)
-
-
-
-
-
乙肝病毒基因型C型
-
-
-
-
-
乙肝病毒型混合型
-
-
-
- {% endcomment %}{# vim: }}} #} diff --git a/97suifangqa/apps/indicator/templates/indicator/SheetDefault.html b/97suifangqa/apps/indicator/templates/indicator/SheetDefault.html index 56d0e6a..88a8d82 100644 --- a/97suifangqa/apps/indicator/templates/indicator/SheetDefault.html +++ b/97suifangqa/apps/indicator/templates/indicator/SheetDefault.html @@ -1,5 +1,7 @@ {% extends "base.html" %} {% load static from staticfiles %} +{% load dict_get %} +{% load divisible_by %} {% block title %} 指标状态 | 随访工具 | 97 随访 @@ -33,200 +35,183 @@ var static_url = "{{ STATIC_URL }}"; var indicator_url = "/indicator/"; + + + {% endblock %} {% block page %} - -
-
-
指标状态
- -
-
以下可能是您感兴趣的指标,您可以点击卡片右上角“X”,取消关注。
-
-
- - - -
-
乙肝病毒核算定量 (PCR)1
-
- 参考范围 - 100 x 10^4 拷贝 /mL -
-
- - - -
-
-
- x 10^ - -
-
-
-
-
- 拷贝 /mL -
-
-
-
-
-
-
-
-
点击右上角的按钮可以编辑数据
- - - - - -
- - -
-
乙肝病毒核算定量 (PCR)2
-
- 参考范围 - 100 x 10^4 拷贝 /mL -
-
- - - -
-
-
- x 10^ - -
-
-
-
-
- 拷贝 /mL -
-
-
-
-
-
-
-
-
点击右上角的按钮可以编辑数据
- - - -
- -
-
乙肝病毒核算定量 (PCR)3
-
- 参考范围 - 100 x 10^4 拷贝 /mL -
-
-
98 x 10^4 拷贝 /mL
- - -
-
-
- x 10^ - -
-
-
-
-
- 拷贝 /mL -
-
-
-
-
这是2013-07-01 化验单上的记录
-
-
-
-
- -
-
- - - -
- -
-
乙肝病毒核算定量 (PCR)4
-
- - -
- - -
-
- - -
-
-
-
-
- - - - - - -
日期时间记录
-
-
-
- -
+ +
+
+
指标状态
+ + +
+
以下可能是您感兴趣的指标,您可以点击卡片右上角“X”,取消关注。
+
+
+ + + + {% for ind in indicators %} +
+
{{ ind|dict_get:"name" }}
+
+ {{ ind|dict_get:"ref_text" }} + {{ ind|dict_get:"ref_value"|safe }} + {{ ind|dict_get:"std_unit_symbol" }} +
+ {% if ind|dict_get:"record_empty" %} {# vim: {{{ #} + {# if no record, then hide 'last_edit_data' #} + +
+ + + +
+
+
+ + x 10^ + +
+
+
+
+
+
{{ ind|dict_get:"std_unit_symbol" }}
+
+
+
+ +
+
+
+
+
+
点击右上角的按钮开始添加数据
+ {# vim: }}} #} + {% else %} {# record_empty == False; vim: {{{ #} + {# indicator has records #} + +
+
+ {{ ind|dict_get:"last_record"|dict_get:"value_str" }} + {{ ind|dict_get:"std_unit_symbol" }} +
+ + +
+
+
+ + x 10^ + +
+
+
+
+
+
{{ ind|dict_get:"std_unit_symbol" }}
+
+
+
+
+
+ 记录日期: {{ ind|dict_get:"last_record"|dict_get:"date" }} +
+
+
+
+
+ +
+ +
+ {% endif %} {# end: record_empty; vim: }}} #} + + + + {% comment %} + thickbox插件: + 方便父级页面与子级弹出层的MVC隔离, + 方便子级弹出层的复杂需求,如:搜索、分页… + height参数为弹出层页面高度+2, + width参数为弹出层页面宽度+2, + card_id参数为 "卡片id" + {% endcomment %} + +
+ {% endfor %} {# end: indicators #} + + +
+
乙肝病毒核算定量 (PCR)4
+
+ + +
+ + +
+
+ + +
+
+
+
+
+ + + + + + +
日期时间记录
+
+
+ +
+
+ + + {% if indicators|length|divisible_by:"2" %} + {# number of followed indicators: even #} +
+ {% else %} + -
-
+
+ +
+
{% endblock page %} {# vim: set ts=2 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #} diff --git a/97suifangqa/apps/indicator/templates/indicator/index.html b/97suifangqa/apps/indicator/templates/indicator/index.html index 7c280f7..408ce67 100644 --- a/97suifangqa/apps/indicator/templates/indicator/index.html +++ b/97suifangqa/apps/indicator/templates/indicator/index.html @@ -8,7 +8,7 @@ {% block body %} {% endblock %} diff --git a/97suifangqa/apps/indicator/templates/indicator/popup/DeleteCardTip.html b/97suifangqa/apps/indicator/templates/indicator/popup/DeleteCardTip.html index 7424930..c978f8a 100644 --- a/97suifangqa/apps/indicator/templates/indicator/popup/DeleteCardTip.html +++ b/97suifangqa/apps/indicator/templates/indicator/popup/DeleteCardTip.html @@ -24,7 +24,9 @@
提示
-
取消关注指标后,该指标卡片将从本页面消失,您确定需要取消关注?
+
+ 取消关注指标后,该指标卡片将从本页面消失,您确定需要取消关注? +
取消关注 继续关注 diff --git a/97suifangqa/apps/indicator/templatetags/divisible_by.py b/97suifangqa/apps/indicator/templatetags/divisible_by.py new file mode 100644 index 0000000..96638e7 --- /dev/null +++ b/97suifangqa/apps/indicator/templatetags/divisible_by.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +from django import template + +register = template.Library() + +@register.filter +def divisible_by(dividend, divisor): + """ + if 'dividend' can be *exactly* divided by 'divisor', + return True; + else, return False. + + input parameters: + dividend: + divisor: + """ + if not isinstance(dividend, int): + raise ValueError(u'Error: dividend="%s" not int type' % dividend) + try: + divisor = int(divisor) + except ValueError, TypeError: + raise ValueError(u'Error: divisor="%s" cannot convert to int' + % divisor) + # + if dividend % divisor == 0: + return True + else: + return False + diff --git a/97suifangqa/apps/indicator/tools.py b/97suifangqa/apps/indicator/tools.py index 663ec4f..a472db5 100644 --- a/97suifangqa/apps/indicator/tools.py +++ b/97suifangqa/apps/indicator/tools.py @@ -5,13 +5,52 @@ utils for apps/indicator """ from django.contrib.auth.models import User +from django.shortcuts import get_object_or_404 from indicator import models as im from sciblog import models as sciblogm +import re import datetime +# follow_indicator {{{ +def follow_indicator(user_id, indicator_id): + """ + 用户关注指标 + """ + try: + user = get_object_or_404(User, id=user_id) + indicator = im.Indicator.objects.get(id=indicator_id) + ui, created = im.UserIndicator.objects.get_or_create(user=user) + ui.followedIndicators.add(indicator) + # to remove the indicator from 'followedHistories' if exists + if indicator in ui.followedHistories.all(): + ui.followedHistories.remove(indicator) + return True + except: + return False +# }}} + + +# unfollow_indicator {{{ +def unfollow_indicator(user_id, indicator_id): + """ + 用户取消关注指标 + """ + try: + user = get_object_or_404(User, id=user_id) + indicator = im.Indicator.objects.get(id=indicator_id) + ui, created = im.UserIndicator.objects.get_or_create(user=user) + ui.followedIndicators.remove(indicator) + # add indicator to 'followedHistories' + ui.followedHistories.add(indicator) + return True + except: + return False +# }}} + + # get_indicator {{{ def get_indicator(category_id="all", startswith="all"): """ @@ -102,7 +141,8 @@ def get_unfollowed_indicator(user_id, category_id="all", startswith="all"): u = User.objects.get(id=user_id) ui, created = im.UserIndicator.objects.get_or_create(user=u) _idict = {} - iqueryset = im.Indicator.objects.exclude(user_indicators=ui) + # XXX: if 'exclude(followed_indicators=ui)' OK?? + iqueryset = im.Indicator.objects.exclude(followed_indicators=ui) if not category_id == 'all': try: cid = int(category_id) @@ -192,25 +232,41 @@ def get_record_std(**kwargs): # }}} +# types of recommended indicators, and weights {{{ +RI_TYPES = { + 'ANNOTATION_COLLECTED': u'ANN_CL', + 'BLOG_CATCHED': u'BLG_CT', + 'BLOG_COLLECTED': u'BLG_CL', + 'OTHER': u'OTHER', + 'ERROR': u'ERROR', # no 'RelatedIndicator' data +} +RI_WEIGHTS = { + RI_TYPES['ANNOTATION_COLLECTED']: 4.0, + RI_TYPES['BLOG_CATCHED']: 3.0, + RI_TYPES['BLOG_COLLECTED']: 2.0, + RI_TYPES['OTHER']: 1.0, + RI_TYPES['ERROR']: 0.0, +} +# }}} + + # calc_indicator_weight {{{ def calc_indicator_weight(user_id, indicator_id): """ calculate the weight of given indicator used by 'recommend_indicator' + + return format: + {'weight': w, 'type': t} """ - ### XXX: weight_type: how to store the weights into database ### - weight_annotation = 4.0 - weight_blog_catched = 3.0 - weight_blog_collected = 2.0 - weight_other = 1.0 - ################################################################ # weight = weight_type * relatedindicator.weight user = User.objects.get(id=user_id) ri_qs = im.RelatedIndicator.objects.filter(indicator__id=indicator_id) if not ri_qs: - # queryset empty + # queryset empty: no 'RelatedIndicator' for this indicator + type = RI_TYPES['ERROR'] w = 0.0 - return w + return {'weight': w, 'type': type} # queryset not empty annotation_ri_qs = ri_qs.filter(annotation__collected_by=user) blogcatch_ri_qs = ri_qs.filter(blog__catched_by=user) @@ -218,26 +274,32 @@ def calc_indicator_weight(user_id, indicator_id): weights = [] if annotation_ri_qs: # related to annotations collected by user + type = RI_TYPES['ANNOTATION_COLLECTED'] for ri in annotation_ri_qs: - w = weight_annotation * ri.weight - weights.append(w) + w = RI_WEIGHTS[type] * ri.weight + weights.append({'weight': w, 'type': type}) elif blogcatch_ri_qs: # related to blogs catched by user + type = RI_TYPES['BLOG_CATCHED'] for ri in blogcatch_ri_qs: - w = weight_blog_catched * ri.weight - weights.append(w) + w = RI_WEIGHTS[type] * ri.weight + weights.append({'weight': w, 'type': type}) elif blogcollect_ri_qs: - # related to blogs catched by user + # related to blogs collected by user + type = RI_TYPES['BLOG_COLLECTED'] for ri in blogcollect_ri_qs: - w = weight_blog_collected * ri.weight - weights.append(w) + w = RI_WEIGHTS[type] * ri.weight + weights.append({'weight': w, 'type': type}) else: # other type, use 'ri_qs' here + type = RI_TYPES['OTHER'] for ri in ri_qs: - w = weight_other * ri.weight - weights.append(w) + w = RI_WEIGHTS[type] * ri.weight + weights.append({'weight': w, 'type': type}) + # sort results + weights_sorted = sorted(weights, key = lambda item: item['weight']) # return final result - return max(weights) + return weights_sorted[-1] # }}} @@ -247,22 +309,25 @@ def recommend_indicator(user_id, number): recommend unfollowed indicator for user, based on his/her readings and collections. - return a list with the id's of recommended indicators - - TODO: - performance test + return a list of recommended indicators in format: + [ {'id': id, 'weight': w, 'type': t}, ... ] """ user_id = int(user_id) number = int(number) # get unfollowed indicators u = User.objects.get(id=user_id) ui, created = im.UserIndicator.objects.get_or_create(user=u) - uf_ind_qs = im.Indicator.objects.exclude(user_indicators=ui) + # XXX: if 'exclude(followed_indicators=ui)' OK?? + uf_ind_qs = im.Indicator.objects.exclude(followed_indicators=ui) # calc weight for each unfollowed indicator weights = [] for ind in uf_ind_qs: - w = calc_indicator_weight(user_id, ind.id) - weights.append({'id': ind.id, 'weight': w}) + wdict = calc_indicator_weight(user_id, ind.id) + weights.append({ + 'id': ind.id, + 'weight': wdict.get('weight'), + 'type': wdict.get('type'), + }) # sort 'weights' dict list by key 'weight' weights_sorted = sorted(weights, key=lambda item: item['weight']) weights_sorted.reverse() @@ -271,3 +336,90 @@ def recommend_indicator(user_id, number): # }}} +# format_data {{{ +def format_data(indicator_obj, value=None, val_max=None, val_min=None): + """ + format given data according to the dataType of given Indicator, + make it proper for django templates + e.g.: + if number very big, then display in 'exponent notation' + + used in '.views.indicator_status()' + """ + # threshold to show a float number in scientific notation + float_threshold = 9999.9 + # float display format: fixed point, exponent notation + fix_fmt = '{:,.1f}' # comma as a thousands separator + exp_fmt = '{:.2e}' + # regex to process exponent notation + rep = re.compile(r'^(?P[-+]?)(?P\d\.\d+)[eE]\+?(?P-?)0*(?P[1-9]+)$') + # range symbol (range: low $symbol$ high) + range_sym = '∼' + # default return value + value_str = u'' + + # check given 'indicator_obj' + ind = indicator_obj + if not isinstance(ind, im.Indicator): + print u'Error: given indicator_obj NOT a instance of Indicator' + raise ValueError(u'Given indicator_obj NOT a instance of Indicator') + # get dataType + dataType = ind.dataType + + if value is not None: + # a) record float data; b) record integer/pm data; + # c) confine integer/pm data. + if dataType == ind.INTEGER_TYPE: + # TODO: process 'integer type' data + value_str = u'INTEGER: %s' % value + elif dataType == ind.PM_TYPE: + if value == u'+': + value_str = u'阳性(+)' + else: + value_str = u'阳性(-)' + elif dataType in [ind.FLOAT_TYPE, ind.FLOAT_RANGE_TYPE]: + # process float number + value = float(value) + if value <= float_threshold: + value_str = fix_fmt.format(value) + else: + value_expstr = exp_fmt.format(value) + # convert to html exponent format + m = rep.match(value_expstr) + value_str = "%s%s×10%s%s" % ( + m.group('sign'), m.group('num'), + m.group('expminus'), m.group('exp')) + else: + # unknown XXX + pass + elif (val_max is not None) and (val_min is not None): + # a) record range data; b) confine range. + # val_max + if val_max <= float_threshold: + val_max_str = fix_fmt.format(val_max) + else: + val_max_expstr = exp_fmt.format(val_max) + # convert to html exponent format + m = rep.match(val_max_expstr) + val_max_str = "%s%s×10%s%s" % ( + m.group('sign'), m.group('num'), + m.group('expminus'), m.group('exp')) + # val_min + if val_min <= float_threshold: + val_min_str = fix_fmt.format(val_min) + else: + val_min_expstr = exp_fmt.format(val_min) + # convert to html exponent format + m = rep.match(val_min_expstr) + val_min_str = "%s%s×10%s%s" % ( + m.group('sign'), m.group('num'), + m.group('expminus'), m.group('exp')) + # value_str + value_str = u'%s %s %s' % (val_min_str, range_sym, val_max_str) + else: + # other type?? + pass + + return value_str +# }}} + diff --git a/97suifangqa/apps/indicator/urls.py b/97suifangqa/apps/indicator/urls.py index 5818616..93f3c7b 100644 --- a/97suifangqa/apps/indicator/urls.py +++ b/97suifangqa/apps/indicator/urls.py @@ -51,10 +51,10 @@ urlpatterns += patterns('indicator.views', url(r'^status/$', 'indicator_status', name='indicator_status'), - # follow_indicator, 关注指标 - url(r'^follow/$', - 'follow_indicator', - name='follow_indicator'), + # indicator_fanduf, 关注指标 + url(r'^follow_and_unfollow/$', + 'indicator_fanduf', + name='indicator_fanduf'), ## indicator: popup # DeleteCardTip url(r'^popup/deletecardtip/$', @@ -94,6 +94,10 @@ urlpatterns += patterns('indicator.views', url(r'^ajax/get_card_data_table/$', 'ajax_get_card_data_table', name='indicator_ajax_getcarddatatable'), + # unfollow_indicator + url(r'^ajax/unfollow_indicator/$', + 'ajax_unfollow_indicator', + name='indicator_ajax_unfollowindicator'), ) urlpatterns += patterns('indicator.views', diff --git a/97suifangqa/apps/indicator/views.py b/97suifangqa/apps/indicator/views.py index f222d10..dc7b902 100644 --- a/97suifangqa/apps/indicator/views.py +++ b/97suifangqa/apps/indicator/views.py @@ -11,10 +11,16 @@ from django.shortcuts import render, get_object_or_404 # CRSF from django.template import RequestContext +# haystack search +from haystack.query import SearchQuerySet + from indicator import models as im from indicator.forms import * from indicator.tools import * +# apps/utils +from utils.search_tools import objects_of_sqs + import re import datetime @@ -51,40 +57,6 @@ def recommend_indicator_view(request, **kwargs): return HttpResponse("%s" % ilist) -# follow_indicator {{{ -@login_required -def follow_indicator(request, indicator_id): - """ - 用户关注指标 - """ - try: - indicator = im.Indicator.objects.get(pk=int(indicator_id)) - ui, created = im.UserIndicator.objects.get_or_create( - user=request.user) - ui.followedIndicators.add(indicator) - return { 'success': True } - except: - return { 'success': False } -# }}} - - -# unfollow_indicator {{{ -@login_required -def unfollow_indicator(request, indicator_id): - """ - 用户取消关注指标 - """ - try: - indicator = im.Indicator.objects.get(pk=int(indicator_id)) - ui, created = im.UserIndicator.objects.get_or_create( - user=request.user) - ui.followedIndicators.remove(indicator) - return { 'success': True } - except: - return { 'success': False } -# }}} - - # get_record_view {{{ @login_required def get_record_view(request, indicator_id, date_range, **kwargs): @@ -445,15 +417,126 @@ def indicator_status(request): """ status page for indicator add/edit/view indicator data + + TODO: + * when to recommend indicators + * how to deal with non-standard units """ template = 'indicator/SheetDefault.html' - return render(request, template) + letters = map(chr, range(ord('a'), ord('z')+1)) + # indicators + indicators = [] + followed_indicators = [] + r_indicators = [] + + # get followed indicator, P[inyin] dict format + followed_indicators_pdict = get_followed_indicator(request.user.id) + # convert to list + for l in letters: + followed_indicators += followed_indicators_pdict[l] + + ## TODO: when to recommend indicators for user ?? + if not followed_indicators: + # if no followed indicators yet, then recommend 2 indicators + r_indicators_unsort = [ + im.Indicator.objects.get(id=ri['id']).dump() + for ri in recommend_indicator(request.user.id, 2) + ] + r_indicators= sorted(r_indicators_unsort, + key = lambda item: item['pinyin']) + + # recommended indicators behind followed ones + indicators = followed_indicators + r_indicators + + # process 'indicators' list, to add following keys: # {{{ + # ref_text: + # ref_value: + # std_unit_symbol: + # record_empty: bool, if has no record, then True + for ind in indicators: + ind_obj = get_object_or_404(im.Indicator, id=ind['id']) + # check if 'indicator.is_ready()' + if not ind_obj.is_ready(): + raise ValueError(u"Indicator id=%s is NOT ready yet!" + % ind_obj.id) + # the indicator is ready + dataType = ind_obj.dataType + confine = ind_obj.get_confine() + ## set 'ref_text', 'ref_value', 'std_unit_*' + if dataType in [ind_obj.FLOAT_TYPE, ind_obj.RANGE_TYPE, + ind_obj.FLOAT_RANGE_TYPE]: + ind['ref_text'] = u"参考范围" + # ref_value + human_max = confine.get('human_max') + human_min = confine.get('human_min') + ind['ref_value'] = format_data(ind_obj, + val_max=human_max, val_min=human_min) + # set 'std_unit_*' + ind['std_unit_name'] = confine.get('unit').get('name') + ind['std_unit_symbol'] = confine.get('unit').get('symbol') + elif dataType in [ind_obj.INTEGER_TYPE, ind_obj.PM_TYPE]: + ind['ref_text'] = u"参考值" + # ref_value + val_norm = confine.get('val_norm') + ind['ref_value'] = format_data(ind_obj, value=val_norm) + # std_unit + ind['std_unit_name'] = u"" + ind['std_unit_symbol'] = u"" + else: + ind['ref_text'] = u"参考" + ind['ref_value'] = None + ind['std_unit_name'] = None + ind['std_unit_symbol'] = None + ## check record of indicator + records = ind_obj.indicator_records.filter(user=request.user).\ + order_by('-date', '-updated_at') + if records: + ind['record_empty'] = False + # last record of the indicator + last_record = records[0] + if dataType in [ind_obj.INTEGER_TYPE, ind_obj.PM_TYPE, + ind_obj.FLOAT_TYPE]: + value_str = format_data(ind_obj, value=last_record.value) + elif dataType == ind_obj.RANGE_TYPE: + value_str = format_data(ind_obj, + val_max=last_record.val_max, + val_min=last_record.val_min) + elif dataType == ind_obj.FLOAT_RANGE_TYPE: + value = last_record.value + val_max = last_record.val_max + val_min = last_record.val_min + if value is not None: + value_str = format_data(ind_obj, value=value) + elif (val_max is not None) and (val_min is not None): + value_str = format_data(ind_obj, + val_max=val_max, val_min=val_min) + else: + value_str = u'' + else: + # unknow + value_str = u'' + # save to dict + ind['last_record'] = { + 'date': last_record.date.isoformat(), + 'value_str': value_str, + } + else: + ind['record_empty'] = True + ind['last_record'] = {} + # }}} + + data = { + 'indicators': indicators, + } + # render template + #raise ValueError + return render(request, template, data) # }}} # indicator/NewDeleteIndex.html {{{ @login_required -def follow_indicator(request): +def indicator_fanduf(request): """ follow/unfollow indicator @@ -471,23 +554,23 @@ def follow_indicator(request): # set default value for 'selected_cat*' selected_catid = None selected_category = None - # get indicators, P[inyin] dict format - indicators_pdict = get_indicator() - # get followed indicator, P[inyin] dict format - followed_indicators_pdict = get_followed_indicator(request.user.id) - # convert to list - followed_indicators = [] - for l in letters: - followed_indicators += followed_indicators_pdict[l] + # default parameters + indicators = None + search_kw_empty = False + search_result_empty = False # get/post views if request.method == 'GET': - if request.GET.get('tab'): + # default page_condition: "all" + selected_catid = "all" + page_condition = "all" + # page_condition: "category" + # select category / search indicator + if 'tab' in request.GET: # tab: selected category, default "all" selected_catid = request.GET.get('tab') - if selected_catid == "all": + if selected_catid == "all" or selected_catid == "": page_condition = "all" - indicators = indicators_pdict else: selected_catid = int(selected_catid) selected_category = get_object_or_404( @@ -496,25 +579,50 @@ def follow_indicator(request): # get indicators of the category indicators = selected_category.indicators.\ all().order_by('pinyin') - elif request.GET.get('kw'): + # page_condition: "search" + # can override the above 'category' if 'tab' & 'kw' both exist + if 'kw' in request.GET: # kw: search keyword to find indicator search_kw = request.GET.get('kw') page_condition = "search" - # TODO - indicators = [] - else: - # default page_condition: "all" - selected_catid = "all" - page_condition = "all" - indicators = indicators_pdict + selected_catid = None + # check search keyword + if search_kw == "": + search_kw_empty = True + else: + # search + # TODO: howto order_by() by 'pinyin' + sqs = SearchQuerySet().models(im.Indicator).\ + filter(content=search_kw) + if sqs: + # search result not empty + inds_unsort = [ind.dump() + for ind in objects_of_sqs(sqs)] + indicators = sorted(inds_unsort, + key = lambda item: item['pinyin']) + else: + search_result_empty = True elif request.method == 'POST': - # do post process + # posted data of followed indicators # TODO - pass + post = request.POST + raise ValueError(u"TODO") else: # XXX raise Http404 + # all indicators + if page_condition == "all": + # get indicators, P[inyin] dict format + indicators = get_indicator() + + # get followed indicator, P[inyin] dict format + followed_indicators_pdict = get_followed_indicator(request.user.id) + # convert to list + followed_indicators = [] + for l in letters: + followed_indicators += followed_indicators_pdict[l] + data = { 'page_condition': page_condition, 'categories': categories, @@ -523,6 +631,8 @@ def follow_indicator(request): 'letters': letters, 'indicators': indicators, 'followed_indicators': followed_indicators, + 'search_kw_empty': search_kw_empty, + 'search_result_empty': search_result_empty, } # render page return render(request, template, data) @@ -537,7 +647,7 @@ def indicator_deletecardtip(request): prompted tip for deleting a card """ template = 'indicator/popup/DeleteCardTip.html' - return render_to_response(template) + return render(request, template) # }}} @@ -548,7 +658,7 @@ def indicator_edithistorydata(request): popup page to edit history data for an indicator """ template = 'indicator/popup/EditHistoryData.html' - return render_to_response(template) + return render(request, template) # }}} @@ -559,30 +669,52 @@ def indicator_indexdesc(request): description for an indicator """ template = 'indicator/popup/IndexDesc.html' - return render_to_response(template) + return render(request, template) # }}} ########################################################### ###### ajax ###### +# ajax_act_index {{{ @login_required def ajax_act_index(request): """ index action (add/minus) follow/unfollow indicator - - TODO: - * howto relate 'index_id' to 'indicator_id'? - * howto implement follow/unfollow indicator function? """ - if request.is_ajax(): - result = 'success' - else: - result = 'fail' - #raise Http404 + # default 'fail' + result = 'fail' + #if request.is_ajax(): + if True: + # check index_id -> indicator_id + if request.GET.get('index_id') is not None: + index_id = request.GET.get('index_id') + try: + indicator_id = int(index_id) + except ValueError: + print u'Error: Given index_id="%s" cannot convert to integer' % indicator_id + result = 'fail' + return HttpResponse(result) + # check 'act': add/minus -> action: follow/unfollow + if request.GET.get('act') is not None: + action = request.GET.get('act') + if action == "add": + # follow + if follow_indicator(request.user.id, indicator_id): + result = 'success' + elif action == "minus": + # unfollow + if unfollow_indicator(request.user.id, indicator_id): + result = 'success' + else: + raise ValueError(u'Error: Given act="%s" unknown' % action) + result = 'fail' + return HttpResponse(result) +# }}} +# ajax_close_sub_title {{{ def ajax_close_sub_title(request): """ close the small prompt banner above the indicator cards @@ -595,8 +727,10 @@ def ajax_close_sub_title(request): result = 'fail' #raise Http404 return HttpResponse(result) +# }}} +# ajax_edit_history_data {{{ @login_required def ajax_edit_history_data(request): """ @@ -609,8 +743,10 @@ def ajax_edit_history_data(request): result = 'fail' #raise Http404 return HttpResponse(result) +# }}} +# ajax_get_card_data_chart {{{ @login_required def ajax_get_card_data_chart(request): """ @@ -634,8 +770,10 @@ def ajax_get_card_data_chart(request): #raise Http404 return HttpResponse(json.dumps(result), mimetype='application/json') +# }}} +# ajax_get_card_data_table {{{ @login_required def ajax_get_card_data_table(request): """ @@ -665,6 +803,32 @@ def ajax_get_card_data_table(request): result = '' #raise Http404 return HttpResponse(result) +# }}} + + +# ajax_unfollow_indicator {{{ +@login_required +def ajax_unfollow_indicator(request): + """ + respone to the ajax request from 'delete_card_tip.js' + unfollow the specified indicator: GET.indicator_id + """ + # default 'fail' + result = 'fail' + if request.is_ajax(): + if request.GET.get('indicator_id') is not None: + indicator_id = request.GET.get('indicator_id') + try: + indicator_id = int(indicator_id) + except ValueError: + print u'Error: Given indicator_id="%s" cannot convert to integer' % indicator_id + result = 'fail' + if unfollow_indicator(request.user.id, indicator_id): + result = 'success' + + # return result + return HttpResponse(result) +# }}} ########################################################### diff --git a/97suifangqa/apps/info/fixtures/initial_data.json b/97suifangqa/apps/info/fixtures/initial_data.json index 9d5a811..4440490 100644 --- a/97suifangqa/apps/info/fixtures/initial_data.json +++ b/97suifangqa/apps/info/fixtures/initial_data.json @@ -4,7 +4,7 @@ "model": "info.keyword", "fields": { "standard_judge": false, - "created_at": "2013-06-08T13:41:51.053", + "created_at": "2013-06-08T13:41:51.053Z", "object_id": null, "content": "\u8c37\u4e19\u8f6c\u6c28\u9176", "user": null, @@ -18,7 +18,7 @@ "model": "info.keyword", "fields": { "standard_judge": false, - "created_at": "2013-06-12T00:46:54.790", + "created_at": "2013-06-12T00:46:54.790Z", "object_id": null, "content": "\u8868\u9762\u6297\u539f", "user": null, @@ -33,7 +33,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.684", + "created_at": "2013-04-23T15:05:12.684Z", "object_id": null, "content": "\u5982\u4f55\u53bb\u5b9a\u4e49\u4e59\u809d\n", "user": 1, @@ -47,7 +47,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.754", + "created_at": "2013-04-23T15:05:12.754Z", "object_id": null, "content": "\u4ec0\u4e48\u662f\u6162\u6027\u4e59\u578b\u809d\u708e\n", "user": 1, @@ -61,7 +61,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.775", + "created_at": "2013-04-23T15:05:12.775Z", "object_id": null, "content": "\u4ec0\u4e48\u662f\u6025\u6027\u4e59\u578b\u809d\u708e\n", "user": 1, @@ -75,7 +75,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.797", + "created_at": "2013-04-23T15:05:12.797Z", "object_id": null, "content": "\u5c0f\u4e09\u9633\u7684\u4e59\u809d\u75c5\u72b6\n", "user": 1, @@ -89,7 +89,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.823", + "created_at": "2013-04-23T15:05:12.823Z", "object_id": null, "content": "\u5c0f\u4e09\u9633\u7684\u4e59\u809d\u4e3a\u4f55\u4f1a\u6bd4\u5927\u4e09\u9633\u96be\u4ee5\u6cbb\u6108\n", "user": 1, @@ -103,7 +103,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.852", + "created_at": "2013-04-23T15:05:12.852Z", "object_id": null, "content": "\u4ec0\u4e48\u662f\u4e59\u809d\uff1f\n", "user": 1, @@ -117,7 +117,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.872", + "created_at": "2013-04-23T15:05:12.872Z", "object_id": null, "content": "\u5c0f\u4e09\u9633\u2019\u8f6c\u5316\u6210\u2018\u5c0f\u4e8c\u9633\u2019\u4ee3\u8868\u4ec0\u4e48\n", "user": 1, @@ -131,7 +131,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.893", + "created_at": "2013-04-23T15:05:12.893Z", "object_id": null, "content": "\u5c0f\u4e09\u9633\u2019\u7684\u4e59\u809d\u75c5\u539f\u5b66\n", "user": 1, @@ -145,7 +145,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.917", + "created_at": "2013-04-23T15:05:12.917Z", "object_id": null, "content": "\u6bcd\u5a74\u4f20\u64ad\u7a76\u7adf\u662f\u600e\u6837\u7684\u5f62\u5f0f\n", "user": 1, @@ -159,7 +159,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.943", + "created_at": "2013-04-23T15:05:12.943Z", "object_id": null, "content": "\u6bcd\u4eb2\u6216\u7236\u4eb2\u5f97\u4e86\u809d\u708e\u662f\u5426\u80fd\u8981\u5c0f\u5b69\n", "user": 1, @@ -173,7 +173,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.964", + "created_at": "2013-04-23T15:05:12.964Z", "object_id": null, "content": "\u82e5\u662f\u4e59\u809d\u60a3\u8005\uff0c\u8fdb\u884c\u6000\u5b55\u7684\u8fc7\u7a0b\u4e2d\u9700\u8981\u6ce8\u610f\u4ec0\u4e48\n", "user": 1, @@ -187,7 +187,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:12.987", + "created_at": "2013-04-23T15:05:12.987Z", "object_id": null, "content": "\u82e5\u662f\u610f\u5916\u6000\u5b55\uff0c\u4f55\u79cd\u60c5\u51b5\u53ef\u4ee5\u4e0d\u5fc5\u6d41\u4ea7 \n", "user": 1, @@ -201,7 +201,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.009", + "created_at": "2013-04-23T15:05:13.009Z", "object_id": null, "content": "\u4ea7\u524d\u4ea7\u4e2d\u4ea7\u540e\u9700\u8981\u6ce8\u610f\u4ec0\u4e48\n", "user": 1, @@ -215,7 +215,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.046", + "created_at": "2013-04-23T15:05:13.046Z", "object_id": null, "content": "\u4ea7\u540e\u9700\u8981\u4f55\u79cd\u65b9\u5f0f\u4fdd\u62a4\u65b0\u751f\u513f\n", "user": 1, @@ -229,7 +229,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.065", + "created_at": "2013-04-23T15:05:13.065Z", "object_id": null, "content": "\u5404\u9879\u6307\u6807\u4ee3\u8868\u4ec0\u4e48\n", "user": 1, @@ -243,7 +243,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.092", + "created_at": "2013-04-23T15:05:13.092Z", "object_id": null, "content": "\u4e24\u5bf9\u534a\n", "user": 1, @@ -257,7 +257,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.121", + "created_at": "2013-04-23T15:05:13.121Z", "object_id": null, "content": "\u7532\u80ce\u86cb\u767d\u662f\u4ec0\u4e48\uff1f\n", "user": 1, @@ -271,7 +271,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.144", + "created_at": "2013-04-23T15:05:13.144Z", "object_id": null, "content": "\u8c37\u4e19\u8f6c\u6c28\u9176\u662f\u4ec0\u4e48\n", "user": 1, @@ -285,7 +285,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.165", + "created_at": "2013-04-23T15:05:13.165Z", "object_id": null, "content": "\u4ec0\u4e48\u662f\u75c5\u6bd2HBV DNA\uff1f\n", "user": 1, @@ -299,7 +299,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.185", + "created_at": "2013-04-23T15:05:13.185Z", "object_id": null, "content": "\u2018\u5927\u4e09\u9633\u2019\u4ee3\u8868\u4ec0\u4e48\n", "user": 1, @@ -313,7 +313,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.213", + "created_at": "2013-04-23T15:05:13.213Z", "object_id": null, "content": "\u5c0f\u4e09\u9633\u4ee3\u8868\u4ec0\u4e48\n", "user": 1, @@ -327,7 +327,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.236", + "created_at": "2013-04-23T15:05:13.236Z", "object_id": null, "content": "\u2018\u5c0f\u4e8c\u9633\u2019\u7684\u6982\u5ff5\n", "user": 1, @@ -341,7 +341,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.256", + "created_at": "2013-04-23T15:05:13.256Z", "object_id": null, "content": "\u76ee\u524d\u533b\u9662\u4f1a\u91c7\u53d6\u54ea\u4e9b\u68c0\u6d4b\u624b\u6bb5\n", "user": 1, @@ -355,7 +355,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.278", + "created_at": "2013-04-23T15:05:13.278Z", "object_id": null, "content": "\u533b\u9662\u5728\u68c0\u6d4b\u4e59\u809d\u60a3\u8005\u662f\u4f1a\u91c7\u53d6\u4f55\u79cd\u68c0\u6d4b\u65b9\u6848\n", "user": 1, @@ -369,7 +369,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.298", + "created_at": "2013-04-23T15:05:13.298Z", "object_id": null, "content": "\u6bcf\u4e00\u79cd\u68c0\u6d4b\u65b9\u6848\u6240\u4ee3\u8868\u7684\u610f\u4e49\n", "user": 1, @@ -383,7 +383,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.319", + "created_at": "2013-04-23T15:05:13.319Z", "object_id": null, "content": "\u5728\u7ed3\u5408\u6307\u6807\u60c5\u51b5\u4e0b\u63a8\u9009\u4f55\u79cd\u5408\u9002\u65f6\u671f \n", "user": 1, @@ -397,7 +397,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.344", + "created_at": "2013-04-23T15:05:13.344Z", "object_id": null, "content": "\u7ed3\u5408\u6307\u6807\u4ee5\u53ca\u7528\u836f\u5386\u53f2\u8fdb\u884c\u5408\u7406\u7684\u89e3\u91ca \n", "user": 1, @@ -411,7 +411,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.367", + "created_at": "2013-04-23T15:05:13.367Z", "object_id": null, "content": "\u8fdb\u884c\u4f55\u79cd\u5176\u4ed6\u65b9\u9762\u7684\u68c0\u6d4b\uff1f \n", "user": 1, @@ -425,7 +425,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.419", + "created_at": "2013-04-23T15:05:13.419Z", "object_id": null, "content": "\u5728\u8fdb\u884c\u4e86\u5e38\u89c4\u68c0\u6d4b\u540e\uff0c\u4e3a\u4f55\u533b\u751f\u8fd8\u4f1a\u5efa\u8bae\u53bb\u505a\u5176\u4ed6\u65b9\u9762\u7684\u68c0\u6d4b\n", "user": 1, @@ -439,7 +439,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.440", + "created_at": "2013-04-23T15:05:13.440Z", "object_id": null, "content": "\u4e3a\u4f55\u8fd9\u79cd\u68c0\u6d4b\u8f83\u4e3a\u6709\u6548\n", "user": 1, @@ -453,7 +453,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.463", + "created_at": "2013-04-23T15:05:13.463Z", "object_id": null, "content": "\u6162\u6027\u4e59\u809d\u80fd\u81ea\u6211\u4fee\u590d\u5417\n", "user": 1, @@ -467,7 +467,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.483", + "created_at": "2013-04-23T15:05:13.483Z", "object_id": null, "content": "\u2018\u5c0f\u4e09\u9633\u2019\u4e59\u809d\u5728\u4f53\u5185\u7684\u75c5\u53d8\u8fc7\u7a0b\n", "user": 1, @@ -481,7 +481,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.501", + "created_at": "2013-04-23T15:05:13.501Z", "object_id": null, "content": "\u809d\u708e\u65f6\u4e3a\u4f55\u8f6c\u6c28\u9176\u5347\u9ad8\n", "user": 1, @@ -495,7 +495,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.524", + "created_at": "2013-04-23T15:05:13.524Z", "object_id": null, "content": "\u6162\u6027\u809d\u708e\u60a3\u8005\u8f6c\u6c28\u9176\u6025\u5267\u5347\u9ad8\u4f1a\u6709\u4ec0\u4e48\u95ee\u9898\n", "user": 1, @@ -509,7 +509,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.543", + "created_at": "2013-04-23T15:05:13.543Z", "object_id": null, "content": "\u8f6c\u6c28\u9176\u5347\u9ad8\uff0c\u5fc5\u5b9a\u662f\u809d\u75c5\u52a0\u91cd\u5417\n", "user": 1, @@ -523,7 +523,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.565", + "created_at": "2013-04-23T15:05:13.565Z", "object_id": null, "content": "\u9488\u5bf9\u4e59\u809d\u75c5\u6bd2\u9700\u8981\u4ec0\u4e48\u6837\u7684\u514d\u75ab\n", "user": 1, @@ -537,7 +537,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.585", + "created_at": "2013-04-23T15:05:13.585Z", "object_id": null, "content": "\u514d\u75ab\u7f3a\u9677\u662f\u4ec0\u4e48\n", "user": 1, @@ -551,7 +551,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.605", + "created_at": "2013-04-23T15:05:13.605Z", "object_id": null, "content": "\u4ec0\u4e48\u6837\u7684\u514d\u75ab\u6cbb\u7597\u4f1a\u6709\u6548\n", "user": 1, @@ -565,7 +565,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.630", + "created_at": "2013-04-23T15:05:13.630Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u4f5c\u7528\u4e8e\u4eba\u4f53\u65f6\u6240\u4ea7\u751f\u7684\u514d\u75ab\u6fc0\u5316\n", "user": 1, @@ -579,7 +579,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.655", + "created_at": "2013-04-23T15:05:13.655Z", "object_id": null, "content": "\u6162\u6027\u4e59\u809d\u7684\u75c5\u53d8\u60c5\u51b5?\n", "user": 1, @@ -593,7 +593,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.681", + "created_at": "2013-04-23T15:05:13.681Z", "object_id": null, "content": "\u6297\u75c5\u6bd2\u6cbb\u7597\u662f\u4ec0\u4e48\n", "user": 1, @@ -607,7 +607,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.704", + "created_at": "2013-04-23T15:05:13.704Z", "object_id": null, "content": "\u6297\u75c5\u6bd2\u6cbb\u7597\u4e0e\u975e\u6297\u75c5\u6bd2\u6cbb\u7597\u7684\u533a\u522b\u70b9\n", "user": 1, @@ -621,7 +621,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.723", + "created_at": "2013-04-23T15:05:13.723Z", "object_id": null, "content": "\u4f55\u65f6\u5f00\u59cb\u542f\u7528\u6297\u75c5\u6bd2\u6cbb\u7597\n", "user": 1, @@ -635,7 +635,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.744", + "created_at": "2013-04-23T15:05:13.744Z", "object_id": null, "content": "\u5bf9\u4e8e\u4e59\u809d\u6cbb\u7597\u6709\u54ea\u4e9b\u836f\u7269\u53ef\u4ee5\u4f7f\u7528\n", "user": 1, @@ -649,7 +649,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.764", + "created_at": "2013-04-23T15:05:13.764Z", "object_id": null, "content": "\u9009\u62e9\u836f\u54c1\u7684\u65f6\u5019\u7ed3\u5408\u6307\u6807\u8fdb\u884c\u5408\u7406\u7684\u63a8\u8350\n", "user": 1, @@ -663,7 +663,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.786", + "created_at": "2013-04-23T15:05:13.786Z", "object_id": null, "content": "\u7ed3\u5408\u6307\u6807\u4ee5\u53ca\u75c5\u53f2\u8fdb\u884c\u5408\u7406\u7684\u89e3\u51b3\u65b9\u6848\u63a8\u8350\n", "user": 1, @@ -677,7 +677,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.807", + "created_at": "2013-04-23T15:05:13.807Z", "object_id": null, "content": "\u9009\u836f\u671f\u95f4\u9700\u8981\u6ce8\u610f\u4ec0\u4e48\n", "user": 1, @@ -691,7 +691,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.830", + "created_at": "2013-04-23T15:05:13.830Z", "object_id": null, "content": "\u6362\u836f\u671f\u95f4\u9700\u8981\u6ce8\u610f\u4ec0\u4e48\n", "user": 1, @@ -705,7 +705,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.848", + "created_at": "2013-04-23T15:05:13.848Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u548c\u6838\u82f7\u7c7b\u836f\u54c1\u5728\u76f8\u5173\u66ff\u6362\u65f6\u9700\u8981\u6ce8\u610f\u4e9b\u4ec0\u4e48\n", "user": 1, @@ -719,7 +719,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.870", + "created_at": "2013-04-23T15:05:13.870Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u7684\u7597\u7a0b\u957f\u77ed\n", "user": 1, @@ -733,7 +733,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.892", + "created_at": "2013-04-23T15:05:13.892Z", "object_id": null, "content": "\u5bf9\u4e8e\u4f7f\u7528\u5e72\u6270\u7d20\u4e4b\u540e\u4e00\u4e9b\u76f8\u5173\u6307\u6807\u7684\u53d8\u5316\u4ee3\u8868\u4ec0\u4e48\n", "user": 1, @@ -747,7 +747,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.914", + "created_at": "2013-04-23T15:05:13.914Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u7684\u6cbb\u7597\u7ec8\u70b9\n", "user": 1, @@ -761,7 +761,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.939", + "created_at": "2013-04-23T15:05:13.939Z", "object_id": null, "content": "\u54ea\u4e9b\u65b9\u9762\u4ee3\u8868\u5e72\u6270\u7d20\u7684\u6cbb\u7597\u7ec8\u70b9\n", "user": 1, @@ -775,7 +775,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.961", + "created_at": "2013-04-23T15:05:13.961Z", "object_id": null, "content": "\u6838\u82f7\u7c7b\u836f\u7269\u7684\u6cbb\u7597\u7ec8\u70b9\n", "user": 1, @@ -789,7 +789,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:13.986", + "created_at": "2013-04-23T15:05:13.986Z", "object_id": null, "content": "\u54ea\u4e9b\u65b9\u9762\u4ee3\u8868\u6838\u82f7\u7c7b\u7684\u6cbb\u7597\u7ec8\u70b9\n", "user": 1, @@ -803,7 +803,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.007", + "created_at": "2013-04-23T15:05:14.007Z", "object_id": null, "content": "\u505c\u836f\u4e4b\u540e\u9700\u8981\u6ce8\u610f\u4e9b\u4ec0\u4e48\n", "user": 1, @@ -817,7 +817,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.123", + "created_at": "2013-04-23T15:05:14.123Z", "object_id": null, "content": "\u5b9e\u65f6\u76d1\u63a7\uff0c\u968f\u8bbf\u662f\u4ec0\u4e48\u610f\u601d\n", "user": 1, @@ -831,7 +831,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.146", + "created_at": "2013-04-23T15:05:14.146Z", "object_id": null, "content": "\u5bf9\u4e8e\u968f\u8bbf\u7a76\u7adf\u6709\u591a\u91cd\u8981\uff0c\u9700\u8981\u8fdb\u884c\u600e\u6837\u7684\u5b9a\u671f\u68c0\u67e5\n", "user": 1, @@ -845,7 +845,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.171", + "created_at": "2013-04-23T15:05:14.171Z", "object_id": null, "content": "\u600e\u6837\u7684\u5b9a\u671f\u68c0\u67e5\u7b26\u5408\u8be5\u540d\u60a3\u8005\u7684\u6cbb\u7597\u8fdb\u5ea6\n", "user": 1, @@ -859,7 +859,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.197", + "created_at": "2013-04-23T15:05:14.197Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u6bcf\u79cd\u836f\u54c1\u7684\u8be6\u7ec6\u8d44\u6599\n", "user": 1, @@ -873,7 +873,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.221", + "created_at": "2013-04-23T15:05:14.221Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u6cbb\u7597\u5728\u77ed\u671f\u5185\u4f1a\u6709\u4ec0\u4e48\u6548\u679c\n", "user": 1, @@ -887,7 +887,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.244", + "created_at": "2013-04-23T15:05:14.244Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u7597\u7a0b\u4e00\u822c\u591a\u957f\n", "user": 1, @@ -901,7 +901,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.266", + "created_at": "2013-04-23T15:05:14.266Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u6cbb\u7597\u8fdc\u671f\u76ee\u6807\u662f\u4ec0\u4e48\n", "user": 1, @@ -915,7 +915,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.285", + "created_at": "2013-04-23T15:05:14.285Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u7684\u836f\u54c1\u6709\u4ec0\u4e48\u4f18\u7f3a\u70b9\n", "user": 1, @@ -929,7 +929,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.310", + "created_at": "2013-04-23T15:05:14.310Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u7684\u4e00\u4e2a\u7597\u7a0b\u7ed3\u675f\u540e\u662f\u5426\u9700\u8981\u66f4\u6362\u4f7f\u7528\u53e6\u4e00\u79cd\u5e72\u6270\u7d20\n", "user": 1, @@ -943,7 +943,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.332", + "created_at": "2013-04-23T15:05:14.332Z", "object_id": null, "content": "\u957f\u6548\u5e72\u6270\u7d20\u7684\u4f18\u7f3a\u70b9\n", "user": 1, @@ -957,7 +957,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.359", + "created_at": "2013-04-23T15:05:14.359Z", "object_id": null, "content": "\u957f\u6548\u5e72\u6270\u7d20\u7684\u6cbb\u7597\u6548\u679c\u5982\u4f55\n", "user": 1, @@ -971,7 +971,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.381", + "created_at": "2013-04-23T15:05:14.381Z", "object_id": null, "content": "\u54ea\u4e9b\u60a3\u8005\u53ef\u4ee5\u4f7f\u7528\u957f\u6548\u5e72\u6270\u7d20\n", "user": 1, @@ -985,7 +985,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.404", + "created_at": "2013-04-23T15:05:14.404Z", "object_id": null, "content": "\u957f\u6548\u5e72\u6270\u7d20\u5bf9\u4e0d\u540c\u57fa\u56e0\u578b\u7684\u60a3\u8005\u7684\u7597\u6548\u5e94\u7b54\u6709\u533a\u522b\u5417\n", "user": 1, @@ -999,7 +999,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.424", + "created_at": "2013-04-23T15:05:14.424Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u662f\u5426\u4e5f\u4f1a\u4ea7\u751f\u8010\u836f\n", "user": 1, @@ -1013,7 +1013,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.446", + "created_at": "2013-04-23T15:05:14.446Z", "object_id": null, "content": "\u5e72\u6270\u7d20\u662f\u5426\u4f1a\u6709\u5f3a\u70c8\u7684\u590d\u53d1\u4f5c\u7528\n", "user": 1, @@ -1027,7 +1027,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.465", + "created_at": "2013-04-23T15:05:14.465Z", "object_id": null, "content": "\u6d3e\u7f57\u6b23\u80fd\u8ffd\u6c42\u8868\u9762\u6297\u539f\u8f6c\u9634\u5417\n", "user": 1, @@ -1041,7 +1041,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.488", + "created_at": "2013-04-23T15:05:14.488Z", "object_id": null, "content": "\u6d3e\u7f57\u6b23\u9002\u7528\u4e8e\u54ea\u7c7b\u75c5\u4eba\n", "user": 1, @@ -1055,7 +1055,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.507", + "created_at": "2013-04-23T15:05:14.507Z", "object_id": null, "content": "\u6d3e\u7f57\u6b23\u6709\u54ea\u4e9b\u4e0d\u826f\u53cd\u5e94\n", "user": 1, @@ -1069,7 +1069,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.527", + "created_at": "2013-04-23T15:05:14.527Z", "object_id": null, "content": "\u54ea\u4e9b\u809d\u75c5\u662f\u6d3e\u7f57\u6b23\u7684\u9002\u5e94\u75c7\n", "user": 1, @@ -1083,7 +1083,7 @@ "fields": { "standard_judge": false, "level": 1, - "created_at": "2013-04-23T15:05:14.546", + "created_at": "2013-04-23T15:05:14.546Z", "object_id": null, "content": "\u4e4b\u524d\u63a5\u53d7\u6838\u82f7\u7c7b\u836f\u6cbb\u7597\u73b0\u5728\u80fd\u6539\u5e72\u6270\u7d20\u5417\n", "user": 1, diff --git a/97suifangqa/apps/sciblog/fixtures/initial_data.json b/97suifangqa/apps/sciblog/fixtures/initial_data.json index 6038ffe..dc7daec 100644 --- a/97suifangqa/apps/sciblog/fixtures/initial_data.json +++ b/97suifangqa/apps/sciblog/fixtures/initial_data.json @@ -248,8 +248,8 @@ "sample": [], "indicators": [ 3, - 2, - 1 + 1, + 2 ], "type": 1 } diff --git a/97suifangqa/apps/sciblog/templatetags/get_range.py b/97suifangqa/apps/sciblog/templatetags/get_range.py new file mode 100644 index 0000000..9ed90c2 --- /dev/null +++ b/97suifangqa/apps/sciblog/templatetags/get_range.py @@ -0,0 +1,7 @@ +from django import template + +register = template.Library() +@register.filter +def get_range(count, start = 0): + return range(start, start + count) + diff --git a/97suifangqa/apps/sciblog/templatetags/tools.py b/97suifangqa/apps/sciblog/templatetags/tools.py deleted file mode 100644 index 9ed90c2..0000000 --- a/97suifangqa/apps/sciblog/templatetags/tools.py +++ /dev/null @@ -1,7 +0,0 @@ -from django import template - -register = template.Library() -@register.filter -def get_range(count, start = 0): - return range(start, start + count) - diff --git a/97suifangqa/apps/utils/search_tools.py b/97suifangqa/apps/utils/search_tools.py new file mode 100644 index 0000000..ff304f7 --- /dev/null +++ b/97suifangqa/apps/utils/search_tools.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +""" +tools for haystack search +""" + +from haystack.query import SearchQuerySet + +import itertools + + +def objects_of_sqs(sqs): + """ + return the corresponding model set of the SearchQuerySet + """ + if isinstance(sqs, SearchQuerySet): + return itertools.imap(lambda x: x.object, sqs) + else: + return sqs + +def limit(seq, count=None): + """ + return the first 'count' items in 'seq' + if 'count=None', then all items returned + """ + return itertools.islice(seq, count) + + diff --git a/97suifangqa/fixtures/initial_data.json b/97suifangqa/fixtures/initial_data.json index 72c778b..642a166 100644 --- a/97suifangqa/fixtures/initial_data.json +++ b/97suifangqa/fixtures/initial_data.json @@ -9,12 +9,12 @@ "is_active": true, "is_superuser": true, "is_staff": true, - "last_login": "2013-08-03T21:06:50.885", + "last_login": "2013-08-03T13:06:50.885Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$H6nJhlyljgc4$KpHXyPQ7yvhbt9TVMgGVslPnKKuCbwL0WsWA0/J0iDI=", "email": "admin@admin.com", - "date_joined": "2013-08-03T21:06:10.807" + "date_joined": "2013-08-03T13:06:10.807Z" } }, { @@ -27,12 +27,12 @@ "is_active": true, "is_superuser": false, "is_staff": false, - "last_login": "2013-08-03T21:07:14.332", + "last_login": "2013-08-03T13:07:14.332Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$9SIFKsWpSUTT$6q0Gl3IwDhVqXw7M7cbrZ6yStxPdlJGZYUY2tVY9fxg=", "email": "", - "date_joined": "2013-08-03T21:07:14.332" + "date_joined": "2013-08-03T13:07:14.332Z" } }, { @@ -45,12 +45,12 @@ "is_active": true, "is_superuser": true, "is_staff": true, - "last_login": "2013-07-20T15:52:13.059", + "last_login": "2013-07-20T07:52:13.059Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$PBu41nJCDoS9$eGwEX8ZeS1Ot/urxOqQgVorHFvC+LAlBX3wKYrbtsFM=", "email": "isuifang@gmail.com", - "date_joined": "2013-04-23T15:04:43.823" + "date_joined": "2013-04-23T07:04:43.823Z" } }, { @@ -63,12 +63,12 @@ "is_active": true, "is_superuser": false, "is_staff": false, - "last_login": "2013-06-24T22:07:56.201", + "last_login": "2013-06-24T14:07:56.201Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$ccvMiwsQB9Cz$EUrqcy7PZ9o4LwPzQPimsLgsrTg8zCtZ5dYNCqbfGzE=", "email": "", - "date_joined": "2013-06-24T22:07:56.201" + "date_joined": "2013-06-24T14:07:56.201Z" } }, { @@ -81,12 +81,12 @@ "is_active": true, "is_superuser": false, "is_staff": false, - "last_login": "2013-07-20T14:55:05.551", + "last_login": "2013-07-20T06:55:05.551Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$10000$I30HnnfWfD4S$DFmzkurup7phJg+Fr8S64XgDTKABkN3ntH/TMsbp6KA=", "email": "", - "date_joined": "2013-07-20T14:55:05.551" + "date_joined": "2013-07-20T06:55:05.551Z" } } ] \ No newline at end of file diff --git a/97suifangqa/isuifangqa.db b/97suifangqa/isuifangqa.db index 85205ae..d68665f 100644 Binary files a/97suifangqa/isuifangqa.db and b/97suifangqa/isuifangqa.db differ diff --git a/97suifangqa/templates/sciblog/blog_list.html b/97suifangqa/templates/sciblog/blog_list.html index 67f2126..e1eb542 100644 --- a/97suifangqa/templates/sciblog/blog_list.html +++ b/97suifangqa/templates/sciblog/blog_list.html @@ -69,7 +69,7 @@