-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.xml
701 lines (608 loc) · 93.8 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Shajiquan's Island</title><link>https://shajiquan.com/</link><description></description><atom:link href="https://shajiquan.com/feed.xml" rel="self"></atom:link><lastBuildDate>Tue, 23 Feb 2016 00:00:00 +0800</lastBuildDate><item><title>Restful API 和管理后台的统一或分离</title><link>https://shajiquan.com/2016/02/restful-api-and-admin/</link><description><h2>原题</h2>
<ul>
<li>标题: 做一个移动 app 的 api,使用 python,有些疑问,请教给位 v 友</li>
<li>网址: <a href="https://www.v2ex.com/t/251411">https://www.v2ex.com/t/251411</a></li>
<li>详情: 第一次写一个 app 的后台 api ,决定用 flask ,提供 api 的同时,通过网页形式提供后台管理,大概思路是 API 返回 JSON 数据,同时提供网页,需不需要把这两部分分开呢,有没有这类的大概框架可供参考呢?</li>
</ul>
<h2>解答</h2>
<p>app 的 api 是给 app 的用户用的,管理后台,是给管理人员用的。其中有共通之处 ,但也会有大量不同之处。</p>
<p>需求、权限、授权机制、深度、广度都有不同。</p>
<p>假设 app 里一个用户要看帖子列表, api 肯定会提供这个接口,还需要授权机制。</p>
<p>按理说,后台也需要这个接口,但后台的需求应该又有所不同,首先授权机制就可能不同。其次对于帖子的搜索方面,需求比 app 端要多一些吧,而面向 app 的 api 未必需要提供这么多的支持,可能只是普通的按日查询,排发布日期排序之类的。</p>
<p>而管理后台可能就需要很多条件了,比如评论数量超过 X 条的,被收藏 Y 次以上的等等。</p>
<p>所以说,在这个层面上,是分开的。</p>
<p>管理后台这边在使用数据时,如果没有更底层的 API 可供调用,那么这个需求,可能就需要管理后台直接去查库,甚至会查 N 张表来建立各种筛选条件。</p>
<p>肯定也有一些接口是可以直接调用 API 的。比如说工具性的、公共性的。不过这还是要取决于 API 那边的授权机制,以及后台的账户体系。</p>
<p>如果为了个别用户的『超级权限』,把 API 搞得巨复杂,巨多权限检测,恐怕也不是个好方案。</p>
<p>这是我自己的一些经验,仅供参考。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Tue, 23 Feb 2016 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2016-02-23:2016/02/restful-api-and-admin/</guid><category>restful</category><category>api</category><category>web-develop</category><category>flask</category><category>python</category></item><item><title>Happy New Year 2016</title><link>https://shajiquan.com/2016/01/happy-new-year-2016/</link><description><p>新年快乐!</p>
<p>愿看到本文的你,在新的一年,身与心,都有更多的收获。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Fri, 01 Jan 2016 00:00:00 +0000</pubDate><guid>tag:shajiquan.com,2016-01-01:2016/01/happy-new-year-2016/</guid></item><item><title>Golang 时间格式化的奇怪设定 —— 为什么你一直出错</title><link>https://shajiquan.com/2015/12/golang-time-format/</link><description><p>今天有人在群里问:</p>
<div class="highlight"><pre>问一个时间格式化问题:
fmt.Println(time.Now().Format(&quot;2006year 01month 02day&quot;))
2015year 12month 18day
fmt.Println(time.Now().Format(&quot;2015year 01month 01day&quot;))
181253year 12month 12day
为什么?
困扰好久
</pre></div>
<p>首先,这是一个很奇葩的问题。</p>
<p>其次,我,以及比我对 Golang 更了解的朋友,都掉过这个坑。我们曾在这个问题上,花了很多时间,最后发现是 Golang 自己的奇怪设定导致。尤其是,一段时间不用 time 包后,过段时间居然又忘了。</p>
<p>然后,怪我们没看文档,可是...</p>
<p>结论:年、月、日、时、分、秒,英文、数字,必须精确地限定到 golang 指定的时间原点:<code>2006-01-02 15:04:05</code></p>
<p>示例:</p>
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;time&quot;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;hello &quot;</span><span class="p">)</span>
<span class="nx">now</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Now</span><span class="p">()</span>
<span class="nx">nowRight</span> <span class="o">:=</span> <span class="nx">now</span><span class="p">.</span><span class="nx">Format</span><span class="p">(</span><span class="s">&quot;2006-01-02 15:04&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">nowRight</span><span class="p">)</span>
<span class="nx">nowWrong</span> <span class="o">:=</span> <span class="nx">now</span><span class="p">.</span><span class="nx">Format</span><span class="p">(</span><span class="s">&quot;2006-01-03日错了 15:05 分错了&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">nowWrong</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">Format</span><span class="p">(</span><span class="s">&quot;Mon Jan _2 15:04:05 2006 年&quot;</span><span class="p">))</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;变态吧!&quot;</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
<p>附,格式化字符串模板、实时运行示例(赞这个服务):</p>
<div class="highlight"><pre><span class="kd">const</span> <span class="p">(</span>
<span class="nx">ANSIC</span> <span class="p">=</span> <span class="s">&quot;Mon Jan _2 15:04:05 2006&quot;</span>
<span class="nx">UnixDate</span> <span class="p">=</span> <span class="s">&quot;Mon Jan _2 15:04:05 MST 2006&quot;</span>
<span class="nx">RubyDate</span> <span class="p">=</span> <span class="s">&quot;Mon Jan 02 15:04:05 -0700 2006&quot;</span>
<span class="nx">RFC822</span> <span class="p">=</span> <span class="s">&quot;02 Jan 06 15:04 MST&quot;</span>
<span class="nx">RFC822Z</span> <span class="p">=</span> <span class="s">&quot;02 Jan 06 15:04 -0700&quot;</span> <span class="c1">// RFC822 with numeric zone</span>
<span class="nx">RFC850</span> <span class="p">=</span> <span class="s">&quot;Monday, 02-Jan-06 15:04:05 MST&quot;</span>
<span class="nx">RFC1123</span> <span class="p">=</span> <span class="s">&quot;Mon, 02 Jan 2006 15:04:05 MST&quot;</span>
<span class="nx">RFC1123Z</span> <span class="p">=</span> <span class="s">&quot;Mon, 02 Jan 2006 15:04:05 -0700&quot;</span> <span class="c1">// RFC1123 with numeric zone</span>
<span class="nx">RFC3339</span> <span class="p">=</span> <span class="s">&quot;2006-01-02T15:04:05Z07:00&quot;</span>
<span class="nx">RFC3339Nano</span> <span class="p">=</span> <span class="s">&quot;2006-01-02T15:04:05.999999999Z07:00&quot;</span>
<span class="nx">Kitchen</span> <span class="p">=</span> <span class="s">&quot;3:04PM&quot;</span>
<span class="c1">// Handy time stamps.</span>
<span class="nx">Stamp</span> <span class="p">=</span> <span class="s">&quot;Jan _2 15:04:05&quot;</span>
<span class="nx">StampMilli</span> <span class="p">=</span> <span class="s">&quot;Jan _2 15:04:05.000&quot;</span>
<span class="nx">StampMicro</span> <span class="p">=</span> <span class="s">&quot;Jan _2 15:04:05.000000&quot;</span>
<span class="nx">StampNano</span> <span class="p">=</span> <span class="s">&quot;Jan _2 15:04:05.000000000&quot;</span>
<span class="p">)</span>
</pre></div>
<div class="iframe-wrapper">
<iframe style="border:1px solid" src="https://wide.b3log.org/playground/0f8c6853610b15ad81512c98b6a250e7.go?embed=true" width="90%" height="600"></iframe>
</div></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Fri, 18 Dec 2015 18:19:00 +0800</pubDate><guid>tag:shajiquan.com,2015-12-18:2015/12/golang-time-format/</guid><category>golang</category></item><item><title>First post by Pelican</title><link>https://shajiquan.com/2015/12/first-post-by-pelican/</link><description><p>此乃正文是也。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Mon, 14 Dec 2015 00:00:00 +0000</pubDate><guid>tag:shajiquan.com,2015-12-14:2015/12/first-post-by-pelican/</guid></item><item><title>Gitit Bigger 介绍及个人使用实践</title><link>https://shajiquan.com/2015/12/gitit-bigger-intruduction/</link><description><p><a href="https://github.com/shajiquan/gitit-bigger">Gitit Bigger</a> 是我给 <a href="https://github.com/jgm/gitit">Gitit</a> 写的一个 warpper。在 Gitit 的基础上,做了很多易用性的改善。</p>
<h2>源起</h2>
<p>折腾 Gitit Bigger,源于我喜欢 Markdown + Git 这种整理文档的方式。市面上类似软件有很多,各种语言开发的。我试过很多,比如 mkdocs、gollum、Realms Wiki,乃至 Moinmoin 2.0(支持 Markdown)。</p>
<p>但是,这些软件要么是与文件系统结合较差,要么是过于复杂,要么是中文支持较差。而我喜欢将文件系统、Git、文件夹、Markdown 这些整合起来使用。</p>
<p>找来找去,找到了 <a href="https://github.com/jgm/gitit">Gitit</a> 。可是 Gitit 也不是没有缺点,比如 Gitit 本身安装可能较为麻烦,Gitit 的编辑功能爆弱,模板也较差(最近才开始支持响应式)。</p>
<p>因此,我在其基础上做了一些包装,使之更能为我所用。</p>
<ul>
<li>Github 地址:<a href="https://github.com/shajiquan/gitit-bigger">https://github.com/shajiquan/gitit-bigger</a></li>
<li>Demo(Read only): <a href="http://wiki.shajiquan.com">http://wiki.shajiquan.com</a></li>
</ul>
<h2>日常使用</h2>
<p>在日常使用中,我的项目文件夹下有两个 <code>gitit config</code> 文件,还有两个 <code>wikidata</code> 文件夹。目的在于,每个配置文件启动一个 gitit 实例,一个是公开的 <a href="http://wiki.shajiquan.com">http://wiki.shajiquan.com</a>,另一个是私人 Wiki。</p>
<p>这两个实例共享一套模板、静态文件,以及 <code>giti-users</code> 文件,即用户账户列表。但它们的 <code>wikidata</code> 是不同的,也就是内容条目不同。</p>
<p><code>wikidata</code> 文件夹其实是一个 Git 仓库,Gitit 会根据配置将所有添加到 Git 仓库暂存区的指定类型文件视作 wiki 条目或目录。</p>
<p>对于私人 wiki,如果想在本地和服务器都运行并且保持同步,我个人采用的方案是使用 Bitbucket 的仓库,因为 Bitbucket 允许免费账户创建私有仓库。</p>
<p>而公开 wiki,则可以使用 github 仓库。</p>
<p>无论是公开 wiki 还是私人 wiki、团队内部 wiki,如果想在多个机器上运行的话,可以使用 ssh-key + crontab 方式自动 pull、push 来保持同步。</p>
<h2>更多</h2>
<p>Gitit Bigger 还提供了一定程度的定制,比如 Google Analytics 统计、是否开启 ACE 编辑器、是否启用 MathJax 数学公式渲染等等。</p>
<p>Gitit Bigger 还提供了一些工具,比如批量修改文件名后缀,方便在不同的 Gitit 版本间切换,也提供了一些运维工具,启动、重启之类。</p>
<p>Gitit Bigger 目前最大的缺憾是编辑器仍然不够好,期待有一天我换上一个更好的编辑器。</p>
<p>其实我更想做的是用 Go 或者 Python 实现一个 Gitit……</p>
<hr />
<p>下面内容来自项目文档</p>
<hr />
<p><strong>浏览</strong></p>
<p><img alt="Gitit Bigger 页面浏览" src="https://raw.githubusercontent.com/shajiquan/gitit-bigger/master/screenshots/view.png" /></p>
<p><strong>编辑</strong></p>
<p><img alt="Gitit Bigger 页面浏览" src="https://raw.githubusercontent.com/shajiquan/gitit-bigger/master/screenshots/edit.png" /></p>
<hr />
<h2>Demo &amp; Screeenshots</h2>
<h2>Demos</h2>
<ul>
<li>Gitit Bigger :<a href="http://wiki.shajiquan.com/gitit-bigger">http://wiki.shajiquan.com/gitit-bigger</a> (Read Only)</li>
<li>Gitit 官方:<a href="http://gitit.net">http://gitit.net</a></li>
</ul>
<h2>截图 Screenshots</h2>
<h3>查看 View</h3>
<ul>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/view.png">view.png</a></li>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/view-ipad-mini.png">view-ipad-mini.png</a></li>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/view-iphone6.png">view-iphone6.png</a></li>
</ul>
<h3>编辑 Edit</h3>
<ul>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/edit.png">edit.png</a></li>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/edit-ipad-mini.png">edit-ipad-mini.png</a></li>
<li><a href="https://github.com/shajiquan/gitit-bigger/blob/master/screenshots/edit-iphone6.png">edit-iphone6.png</a></li>
</ul>
<h2>Gitit 主要特性</h2>
<ul>
<li>无数据库</li>
<li>Git 版本控制</li>
<li>Markdown 格式</li>
<li>Wiki 化:<ul>
<li>子目录,无限目录(这也是我抛弃其他一些类似 wiki 系统的原因)</li>
<li>中文目录、中文标题、中文分类</li>
<li>完美支持中文搜索</li>
<li>支持分类</li>
<li>支持自定义标题</li>
</ul>
</li>
<li>代码高亮</li>
<li>支持公式等(我基本不用)</li>
<li>导出 epub 等(基于 pandoc )</li>
</ul>
<p>更多关于 Gitit 的安装、部署、优化的中文介绍和说明,请见:<br />
- <a href="https://github.com/shajiquan/gitit-bigger/blob/master/docs/gitit_base.md">gitit_base.md 简介、安装、部署</a><br />
- <a href="https://github.com/shajiquan/gitit-bigger/blob/master/docs/gitit_config.md">gitit_config.md 配置</a></p>
<h2>Gitit Bigger VS Gitit</h2>
<ul>
<li>Bootstrap 模板</li>
<li>Ace Editor</li>
<li>Ace Editor 的编辑模式已设为 <code>markdown</code>。<ul>
<li>支持代码高亮</li>
<li>搜索、替换( cmd+option+f )</li>
<li>Tab 缩进、恢复( tab 、 shift+tab )</li>
<li>快捷键</li>
<li>...</li>
</ul>
</li>
<li>采用配置文件方式启动,多个实例轻松共享资源</li>
<li>支持自定义 Ace 编辑器启用 /禁用、模式、样式等配置</li>
<li>支持 Markdown 模式下快捷键</li>
<li>数学公式:支持 MathJax 启用 /禁用,自定义 MathJax 源</li>
<li>代码高亮:支持使用 highlight.js 高亮代码 - Gitit 的高亮需要服务端支持</li>
<li>增加启动、部分、自动备份脚本或帮助</li>
</ul>
<h2>注意: wikidata 仓库</h2>
<p>请注意检查你的 <code>wikidata/</code> 目录的 git 配置。请注意:<br />
- <code>wikidata</code> 文件夹是一个本地仓库,所有的 wiki 页面都将保存到此处;<br />
- <code>Gitit</code> 启动时,会检查这个文件夹是否存在,如果不存在, Gitit 将会创建它,并初始化它为一个本地仓库<br />
- 只有提交到仓库里的文件,才会被 Gitit 添加到 wiki 中。<br />
- 如果你想要将此仓库与你的远程仓库绑定、同步:你需要:<br />
- clone 你的 wiki 仓库到 <code>wikidata</code> 文件夹:<code>git clone your-wikidata.git ./wikidata</code>,或者:<br />
- 运行 <code>git remote</code> 相关命令,使 <code>wikidata</code> 文件夹和你的远程仓库连接起来;</p>
<pre>
\# 如果 wikidata 文件夹尚不存在cd ~/workspace/gitit
git clone your-wikidata.git ./wikidata
git branch --set-upstream-to=origin/master master
\# 启动 gitit 服务: ./run/run.sh start
\# 如果 wikidata 已经存在,但并没有和你的远程仓库绑定
cd wikidata
git remote add origin path/to/your-wikidata.git
git branch --set-upstream-to=origin/master master
\# 启动 gitit 服务: ./run/run.sh start
</pre>
<h2>配置、自定义 JS/CSS</h2>
<p>Gitit Bigger 提供一定程度的配置。</p>
<p>你可以通过在 <code>templates/page_more_scripts.st</code> 里定义 <code>BIGGER_SETTINGS_APPEND</code> 对象来覆盖默认配置。</p>
<p>包括:<br />
- ace 编辑器<br />
- markdown<br />
- MathJax 数学公式插件<br />
- highlightjs 代码高亮<br />
- Google Analytics 统计</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Fri, 11 Dec 2015 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2015-12-11:2015/12/gitit-bigger-intruduction/</guid><category>git</category><category>gitit</category><category>gitit-bigger</category><category>wiki</category><category>markdown</category><category>document-manager</category><category>projects</category></item><item><title>Flask 路由中的 endpoint view function 等概念的逻辑与流程</title><link>https://shajiquan.com/2015/11/flask-route-endpoint-view-funtion/</link><description><h2>原题</h2>
<ul>
<li>标题:Flask里endpoint view function 路由等概念如何理解</li>
<li>网址:<a href="http://segmentfault.com/q/1010000003875420/a-1020000004002578">http://segmentfault.com/q/1010000003875420/a-1020000004002578</a></li>
<li>详情:</li>
</ul>
<p>在如下这段话中:</p>
<p>http://segmentfault.com/a/1190000002172627</p>
<blockquote>
<p>url_for()唯一必须的参数就是endpoint名,也是每个路由的内部名。默认情况下,路由的endpoint是一个附加到视图函数的名称。在这个示例中,处理根URL的视图函数为index(),所以给url_for()的名称为index。</p>
</blockquote>
<p>可以根据如下代码为参照进行解说:
1. 路由的内部名字是什么?
2. endpoint是一个附加到视图函数的名称,所以,endpoint名就是视图函数的名称么?
3. 为什么需要endpoint参数的时候,需要把视图函数的名称传进去?</p>
<div class="highlight"><pre>@app.route(&#39;/&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;])
def index():
form = NameForm()
if form.validate_on_submit():
session[&#39;name&#39;] = form.name.data
return redirect(url_for(&#39;index&#39;))
return render_template(&#39;index.html&#39;, form=form, name=session.get(&#39;name&#39;))
</pre></div>
<h2>解答:</h2>
<h3>概念</h3>
<ul>
<li>路由规则表 url_map._rules<ul>
<li>Rule 规则之一<ul>
<li>函数 / view function - 处理某个 endpoint/path 的视图函数。可简单理解为,处理某个/组 URL 的函数。</li>
<li>终点 / endpoint - flask 内部的标识</li>
<li>其他 / Rule 规则转换器、methods 之类的</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>流程:</h3>
<ol>
<li>创建 Rule/path</li>
<li>为 Rule/path 分配 endpoint</li>
<li>为 Rule/path 指定 view function.</li>
</ol>
<h3>重点</h3>
<ol>
<li>一个 request 进来的时候,是依据 <code>rule/path</code> 来定位到 app 内部的,也就是说:<ul>
<li>当用户请求 <code>/a</code> 时,会调用 <code>/a</code> 条路由规则指定的视图函数来处理这个请求。</li>
<li>同理,<code>/users/&lt;string:username&gt;</code> 也是一样。</li>
</ul>
</li>
<li>在 flask 的 url_map 路由表中,<code>rule</code>/<code>path</code> 和 <code>endpoint</code> 在路由规则表里都是唯一的<ul>
<li>尤其是 <code>endpoint</code>,如果重复会报错。</li>
<li><code>rule/path</code>,虽然可以重复,但其实只有第一条会生效。</li>
</ul>
</li>
<li>如果开发者没有在 <code>@app.route</code> 装饰器或 <code>app.add_url_rule()</code> 函数调用处指定 endpoint 的话,flask 会为这条 <strong>Rule 规则</strong> 指定一个默认的 endpoint,即这个 <code>view function</code> 的名字。</li>
</ol>
<h3>关系</h3>
<ul>
<li>一个 <code>view function</code>,可以有多个 <code>endpoint</code>、<code>rule</code>。是个一对多的关系。</li>
<li>反过来,一个 <code>endpoint</code>,只能有一个 <code>rule</code>, 也只能有一个 <code>view function</code>。</li>
</ul>
<h3>答案与解释</h3>
<p>现在,回头来看题主的疑问。</p>
<p>1 . 『路由的内部名字是什么?』</p>
<p>名字是:<code>index</code>。</p>
<p>在题主所说的下面的这个视图中,endpoint/路由规则表内部名称是 <code>index</code>,因为并未在 <code>@app.route</code> 函数调用中<strong>显式</strong>指定 endpoint。</p>
<div class="highlight"><pre>@app.route(&#39;/&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;])
def index():
form = NameForm()
if form.validate_on_submit():
session[&#39;name&#39;] = form.name.data
return redirect(url_for(&#39;index&#39;))
return render_template(&#39;index.html&#39;, form=form, name=session.get(&#39;name&#39;))
</pre></div>
<p>2 . 『endpoint 是一个附加到视图函数的名称,所以,endpoint名就是视图函数的名称么?』</p>
<p>不是。正如上面 <strong>重点</strong> 处所说,如果没有<strong>显式</strong>指定 endpoint,flask 会将视图函数的名称也即此处的 <code>index</code> 当作此路由规则的 endpoint。</p>
<p>3 . 『为什么需要endpoint参数的时候,需要把视图函数的名称传进去?』</p>
<p>并非是 <strong>视图函数的名称</strong>,其实是 <code>endpoint</code> 的名字,只不过正巧在某些时候,endpoint 的名字和<strong>视图函数的名称</strong>是一样的。</p>
<h3>Demo</h3>
<div class="highlight"><pre><span class="c">#!/usr/bin/env python3</span>
<span class="c"># coding=utf-8</span>
<span class="kn">import</span> <span class="nn">flask</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">flask</span><span class="o">.</span><span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
<span class="nd">@app.route</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="s">&quot;home&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">amihome</span><span class="p">():</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> 请尝试以 `/` 和 `/shajiquan` 两个路径来访问;</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="s">&quot;View function: {view}. Endpoint: {endpoint}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">view</span><span class="o">=</span><span class="s">&quot;amihome&quot;</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="n">flask</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">endpoint</span><span class="p">)</span>
<span class="c"># 给 app 添加一条 url rule, 指定 rule, endpoint, 但不指定 view function.</span>
<span class="n">app</span><span class="o">.</span><span class="n">add_url_rule</span><span class="p">(</span><span class="n">rule</span><span class="o">=</span><span class="s">&#39;/shajiquan&#39;</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="s">&quot;shajiquan&quot;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">&quot;GET&quot;</span><span class="p">,</span> <span class="s">&quot;DELETE&quot;</span><span class="p">])</span>
<span class="c"># 为 endpoint=&quot;shajiquan&quot; 指定 view function</span>
<span class="n">app</span><span class="o">.</span><span class="n">view_functions</span><span class="p">[</span><span class="s">&#39;shajiquan&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">amihome</span>
<span class="nd">@app.route</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">miao</span><span class="p">():</span>
<span class="k">return</span> <span class="s">&quot;wu at: {}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">flask</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">endpoint</span><span class="p">)</span>
<span class="c"># 尝试取消注释</span>
<span class="c"># app.view_functions[&#39;home&#39;] = miao</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">debug</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">8964</span><span class="p">)</span>
</pre></div></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Mon, 16 Nov 2015 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2015-11-16:2015/11/flask-route-endpoint-view-funtion/</guid><category>flask</category><category>python</category><category>web-develop</category></item><item><title>Flask Web 开发:管理后台删除条目的前后端示例</title><link>https://shajiquan.com/2015/09/flask-web-admin-delete-post/</link><description><h2>问题</h2>
<ul>
<li>标题:flask写的博客页面,现在要对文章进行删除,是怎样的一个操作思路的</li>
<li>网址:<a href="http://segmentfault.com/q/1010000003753099/a-1020000003772140">http://segmentfault.com/q/1010000003753099/a-1020000003772140</a></li>
<li>详情:</li>
</ul>
<p><img alt="图片描述" src="https://sfault-image.b0.upaiyun.com/281/071/2810710213-55f8e42aa1f70_articlex" /></p>
<p>web页面进行点击删除操作后,服务端应该怎样处理的?怎样接受这个删除指令的?</p>
<h2>解答</h2>
<ol>
<li>
<p>客户端发起一个 ajax post 请求,url 为 <code>/post/&lt;post_id&gt;/delete</code>,期待返回的数据类型为 <code>JSON</code>。 </p>
<ul>
<li><code>post_id</code> 为你从前端拿到的这个 post 的 id。</li>
</ul>
</li>
<li>
<p>服务端做处理,可能包括:</p>
<ul>
<li>验证当前用户是否有模块级别权限(假如你需要);</li>
<li>检查该 id 对应的 post 是否存在;<ul>
<li>如果不存在:返回一个 JSON 数据给前端,JSON 对象类似 <code>{'status':404,'message':'Not Found'}</code>。如此,前端就知道这个条目不存在。</li>
<li>如果存在:<ul>
<li>检查当前用户是否具有条目删除权限;<ul>
<li>如果没有权限:返回类似上面的 JSON 数据,但 <code>status</code> 码要重写一下,好让客户端知道这是个什么类型的错误。</li>
<li>如果有权限:将条目标记为删除状态,或者直接从库里删除。返回类似 <code>{'status':0,'message':'success'}</code>,客户端就可以凭借 <code>status=1</code> 判断出了删除成功。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>客户端在向服务端发起请求后,收到服务端返回的 JSON 数据,根据 status 值不同,做不同的处理。比如,假如 status 等于 1,那就代表删除成功,客户端就可以重新加载当前页面,或者利用前端技术把当前行从 table 中删除或者隐藏。</p>
</li>
</ol>
<p><code>status</code>、<code>message</code> 这些键名及其对应的值,客户端和服务端协商定义一个就好了。</p>
<p>Python 代码:</p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">json</span>
<span class="nd">@app.route</span><span class="p">(</span><span class="s">&#39;/post/&lt;int:post_id&gt;/delete&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">post_delete</span><span class="p">(</span><span class="n">post_id</span><span class="p">):</span>
<span class="n">res</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">&quot;status&quot;</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span>
<span class="s">&quot;message&quot;</span><span class="p">:</span><span class="s">&quot;success&quot;</span>
<span class="p">}</span>
<span class="n">post</span> <span class="o">=</span> <span class="n">get_post_by_id</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">post_id</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">post</span><span class="p">:</span>
<span class="n">res</span><span class="p">[</span><span class="s">&#39;status&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="mi">404</span>
<span class="n">res</span><span class="p">[</span><span class="s">&quot;message&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;Post Not Found&quot;</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
<span class="n">delete_post_by_id</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">post_id</span><span class="p">)</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
</pre></div>
<p>前端 html 代码(列表中删除按钮部分):</p>
<div class="highlight"><pre><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;#&quot;</span> <span class="na">class=</span><span class="s">&quot;btn btn-warn btn-sm btn-delete-post&quot;</span> <span class="na">id=</span><span class="s">&quot;列表渲染时拿到的当前post 的 id &quot;</span><span class="nt">&gt;</span>删除<span class="nt">&lt;/a&gt;</span>
<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;#&quot;</span> <span class="na">class=</span><span class="s">&quot;btn btn-warn btn-sm btn-delete-post&quot;</span> <span class="na">id=</span><span class="s">&quot;12345&quot;</span><span class="nt">&gt;</span>删除<span class="nt">&lt;/a&gt;</span>
</pre></div>
<p>前端 ajax 代码:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;a.btn-delete-post&#39;</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;click&#39;</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">evt</span><span class="p">){</span>
<span class="nx">evt</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">post_id</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">);</span>
<span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
<span class="nx">url</span><span class="o">:</span> <span class="s2">&quot;/post/&quot;</span> <span class="o">+</span> <span class="nx">post_id</span><span class="o">+</span> <span class="s2">&quot;/delete&quot;</span><span class="p">,</span>
<span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;POST&quot;</span><span class="p">,</span>
<span class="nx">dataType</span><span class="o">:</span> <span class="s2">&quot;JSON&quot;</span><span class="p">,</span>
<span class="nx">success</span><span class="o">:</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">){</span>
<span class="k">if</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">status</span> <span class="o">!=</span> <span class="mi">1</span> <span class="p">){</span>
<span class="c1">// 不等于 1 则说明删除失败,原因有很多,具体呢,就是服务端返回的 resp.message</span>
<span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;删除失败,原因:&quot;</span><span class="o">+</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// resp.status 等于 1 时,则说明成功,前端处理,此处为重新加载本页。</span>
<span class="nx">location</span><span class="p">.</span><span class="nx">reload</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">})</span>
<span class="p">})</span>
</pre></div></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Mon, 21 Sep 2015 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2015-09-21:2015/09/flask-web-admin-delete-post/</guid><category>flask</category><category>web-develop</category><category>python</category><category>frontend</category></item><item><title>SNS 网络用户关系表结构设计</title><link>https://shajiquan.com/2015/01/sns-relationship-sql-struct/</link><description><h2>原题:</h2>
<ul>
<li>标题:社交网站的用户关系数据是怎么设计的,比如关注数,黑名单数,粉丝数等等。</li>
<li>网址:<a href="http://segmentfault.com/q/1010000002477782">http://segmentfault.com/q/1010000002477782</a></li>
<li>问题详情:</li>
</ul>
<div class="highlight"><pre>我见过一种设计,在数据库里面有一张用户关系表,表结构如下
CREATE TABLE relation (
relation_id private key AUTO_INCREMENT,//关系id
relation_fans text,//粉丝数据
relation_black text,//黑名单数据
relation_action text//关注数据
);
这样的设计有什么用意,如果要取得用户的关系数据 怎么取得?
</pre></div>
<h2>回答:</h2>
<p><code>text</code>类型?是存些什么东西呢?很好奇。另外 <code>private key</code> 是笔误还是?</p>
<p>你列出的这个 demo 里,我看不出来如何获得用户的关系数据。我自己设计时(当然也是我认为合理的方式)是这样的(不完全照搬我自己的,是根据你的这个表改了一下):</p>
<div class="highlight"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">relation</span> <span class="p">(</span>
<span class="n">id</span> <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span> <span class="o">//</span> <span class="err">主键,自增</span>
<span class="n">from_user_id</span> <span class="n">big</span> <span class="nb">integer</span><span class="p">,</span> <span class="o">//</span> <span class="err">用户</span> <span class="n">A</span> <span class="err">的</span> <span class="n">id</span>
<span class="n">to_user_id</span> <span class="n">big</span> <span class="nb">integer</span><span class="p">,</span><span class="o">//</span> <span class="err">用户</span> <span class="n">B</span> <span class="err">的</span> <span class="n">Id</span>
<span class="n">rel_type</span> <span class="n">enum</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span> <span class="o">//</span> <span class="err">关注数据</span>
<span class="p">);</span>
</pre></div>
<p>拉黑/粉丝/关注,在数据库里,存的都是一个映射关系的数字。比如,拉黑是 1,粉丝/关注是一个东西,是 2。那么,一条记录里的关键数据是:
- <code>from_user_id</code> // 本条记录是哪个用户发起
- <code>to_user_id</code> // 本条记录的接受方是哪个用户
- <code>rel_type</code> // 发起者对接受者,做了什么事情?存事情的类型</p>
<h3>场景举例</h3>
<p><strong>用户 A 关注用户 B</strong></p>
<p>插入数据:</p>
<div class="highlight"><pre><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">relation</span> <span class="p">(</span><span class="n">rel_type</span><span class="p">,</span> <span class="n">from_user_id</span><span class="p">,</span> <span class="n">to_user_id</span><span class="p">)</span> <span class="k">VALUES</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">A</span><span class="p">.</span><span class="n">id</span><span class="p">,</span> <span class="n">B</span><span class="p">.</span><span class="n">id</span><span class="p">)</span>
</pre></div>
<p><strong>用户A的粉丝数:</strong></p>
<div class="highlight"><pre><span class="k">select</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">from</span> <span class="n">relation</span>
<span class="k">where</span> <span class="n">rel_type</span><span class="o">=</span><span class="mi">2</span> <span class="k">and</span> <span class="n">to_user_id</span><span class="o">=</span><span class="n">A</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</pre></div>
<p>黑名单同理。</p>
<p>这是按照你给出的表的方式处理的。我自己在做设计的时候,其实是给 关注/粉丝 建了一张表,黑名单又建一张表。按自己的需求和习惯来就好了,无所谓选哪种。</p>
<p>希望有用。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Sun, 11 Jan 2015 00:00:00 +0000</pubDate><guid>tag:shajiquan.com,2015-01-11:2015/01/sns-relationship-sql-struct/</guid><category>sns</category><category>sql</category><category>database</category></item><item><title>私信系统的数据库设计及业务处理 - Sqlalchemy 版</title><link>https://shajiquan.com/2014/12/message-system-sql-schema-sqlalchemy/</link><description><h2>原题</h2>
<ul>
<li>标题: Sqlalchemy复杂查询问题</li>
<li>网址: <a href="http://segmentfault.com/q/1010000002434364/a-1020000002435645">http://segmentfault.com/q/1010000002434364/a-1020000002435645</a></li>
<li>详情:</li>
</ul>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">MessageLog</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;messagelogs&#39;</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">receiver_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;users.id&#39;</span><span class="p">))</span>
<span class="n">message_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;messages.id&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">messagelog_status</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;messagelog_status&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;unread&#39;</span><span class="p">,</span> <span class="s">&#39;read&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Message&quot;</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="s">&quot;receivers&quot;</span><span class="p">)</span>
<span class="n">receiver</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;User&quot;</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="n">backref</span><span class="p">(</span><span class="s">&quot;receive_messages&quot;</span><span class="p">,</span> <span class="n">cascade</span><span class="o">=</span><span class="s">&quot;all, delete, delete-orphan&quot;</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">Message</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;messages&#39;</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">sender_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;users.id&#39;</span><span class="p">))</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">256</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;message_types&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;private&#39;</span><span class="p">,</span> <span class="s">&#39;public&#39;</span><span class="p">,</span> <span class="s">&#39;global&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">posted_at</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">func</span><span class="o">.</span><span class="n">current_timestamp</span><span class="p">())</span>
<span class="n">message_status</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;message_status&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;draft&#39;</span><span class="p">,</span> <span class="s">&#39;sent&#39;</span><span class="p">,</span> <span class="s">&#39;deleted&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">sender</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;User&quot;</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="s">&quot;sent_messages&quot;</span><span class="p">)</span>
</pre></div>
<p>以上是站内信相关的模型,基于这篇文章</p>
<div class="highlight"><pre>http://www.cnblogs.com/hejiaquan/archive/2012/04/07/2435817.html
</pre></div>
<p>用户登录,查询未读信件,推送消息。</p>
<p>系统消息只插入Message表, type=global。
查询的时候,保存在Message表里但又不在MeesageLog里面的message记录是系统站内信。</p>
<p>如何一次查询,即可得到(MessageLog.receiver_id=logged_in.id) 和 系统消息里面的所有未读记录?</p>
<ul>
<li>
<p>追加问题:两个人的来往私信, 如何查询</p>
<p><code>session.query(MessageLog, Message).filter(.message_id == ..id)</code></p>
<p>收件人=我,发件人=对方 || 收件人=对方,发件人=我</p>
</li>
<li>
<p>追加问题2:如何在Sqlalchemy里面查询的时候,动态地插入一条数据??</p>
</li>
<li>追加问题3:如何查询我有多少联系人?(给我发信的人 + 接收我信件的人)</li>
</ul>
<h2>解答</h2>
<p>尝试回答一下。</p>
<p>我觉得这样的设计,把问题复杂化了。为什么不只做一张表呢?<code>Message</code>这张表,只有 sender_id,没有 receiver_id。用户 A 给用户 B 发消息,程序要操作两张表(message 和 messagelog)?好奇怪。</p>
<p>我认为更好的设计是只有一张表,包含了 sender_id、reciever_id、message_status、messagelog_status 等;</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Message</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;messages&#39;</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">sender_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;users.id&#39;</span><span class="p">))</span>
<span class="n">receiver_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;users.id&#39;</span><span class="p">))</span> <span class="c"># 新增</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">256</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;message_types&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;private&#39;</span><span class="p">,</span> <span class="s">&#39;public&#39;</span><span class="p">,</span> <span class="s">&#39;global&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">posted_at</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">func</span><span class="o">.</span><span class="n">current_timestamp</span><span class="p">())</span>
<span class="n">message_status</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;message_status&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;draft&#39;</span><span class="p">,</span> <span class="s">&#39;sent&#39;</span><span class="p">,</span> <span class="s">&#39;deleted&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">messagelog_status</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;messagelog_status&#39;</span><span class="p">,</span> <span class="n">Enum</span><span class="p">(</span><span class="s">&#39;unread&#39;</span><span class="p">,</span> <span class="s">&#39;read&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="c"># 新增</span>
</pre></div>
<p>So,问题解析和解答:</p>
<p><strong>如何一次查询,即可得到(MessageLog.receiver_id=logged_in.id) 和 系统消息里面的所有未读记录?</strong></p>
<p>也即 <strong> 得到当前登录用户(loggined_id)应该收到的两类消息:系统消息、指定发给 TA 的。 </strong></p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">sqlalchemy</span> <span class="kn">as</span> <span class="nn">sa</span>
<span class="n">messages</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Message</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
<span class="n">sa</span><span class="o">.</span><span class="n">or_</span><span class="p">(</span>
<span class="n">Message</span><span class="o">.</span><span class="n">receiver_id</span> <span class="o">==</span> <span class="n">logged_in</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
<span class="n">sa</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">Message</span><span class="o">.</span><span class="n">type</span><span class="o">==</span><span class="s">&#39;global&#39;</span><span class="p">,</span><span class="n">Message</span><span class="o">.</span><span class="n">messagelog_status</span><span class="o">==</span><span class="s">&#39;unread&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="p">)</span>
</pre></div>
<p><strong> 两个人的来往私信 </strong></p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">sqlalchemy</span> <span class="kn">as</span> <span class="nn">sa</span>
<span class="n">user_id_a</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">user_id_b</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">messages</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Message</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
<span class="n">sa</span><span class="o">.</span><span class="n">or_</span><span class="p">(</span>
<span class="n">sa</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">Message</span><span class="o">.</span><span class="n">sender_id</span><span class="o">==</span><span class="n">user_id_a</span><span class="p">,</span><span class="n">Message</span><span class="o">.</span><span class="n">receiver_id</span><span class="o">=</span><span class="n">user_id_b</span><span class="p">),</span>
<span class="n">sa</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">Message</span><span class="o">.</span><span class="n">sender_id</span><span class="o">==</span><span class="n">user_id_b</span><span class="p">,</span><span class="n">Message</span><span class="o">.</span><span class="n">receiver_id</span><span class="o">=</span><span class="n">user_id_a</span><span class="p">)</span>
<span class="p">)</span>
<span class="p">)</span>
</pre></div>
<p><strong> 如何在Sqlalchemy里面查询的时候,动态地插入一条数据?</strong></p>
<p>交给接口去处理。callback 什么的。</p>
<p>另外,不建议在 sender_id 和 receiver_id 处使用 ForeignKey,就直接 Integer 好了。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Sun, 21 Dec 2014 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2014-12-21:2014/12/message-system-sql-schema-sqlalchemy/</guid><category>python</category><category>sql</category><category>database</category><category>sqlalchemy</category></item><item><title>Flask 如何实现类似 web.py 的 URL 映射?</title><link>https://shajiquan.com/2014/11/flask-webpy-routing/</link><description><h1>原题:</h1>
<ul>
<li>标题:flask 如何实现类似 web.py 的 URL 映射?</li>
<li>网址:<a href="https://segmentfault.com/q/1010000000764523/a-1020000000765883">https://segmentfault.com/q/1010000000764523/a-1020000000765883</a></li>
<li>问题详情:如题,如何实现类似 webpylike.py 的 web.py 风格的 URL 映射?</li>
</ul>
<h1>解答</h1>
<p>楼主问的应该是基于 <code>method</code> 的 restful 类的视图实现。flask 有提供 <code>flask.views.MethodView</code>,demo 见:http://docs.jinkan.org/docs/flask/views.html#id4</p>
<p>但并不建议用这种方法。因为:
因为从调用者的视角来看 <code>self</code> 是不明确的,所以你不能在单独的视图方法上使用常规的视图装饰器,请记住这些。</p>
<p>也就是说,class 中有若干个方法,比如 <code>get</code>、<code>post</code>、<code>put</code>、<code>delete</code> 等,但你没法单独为这些方法添加装饰器,你只能给整个 class 添加。</p>
<p><code>tornado</code> 可以。</p>
<p>我最早用 <code>tornado</code>,后来想试下 <code>flask</code>,发现这个问题后,我就决定只用 flask 的 <code>blueprint</code><a href="http://docs.jinkan.org/docs/flask/blueprints.html">蓝图</a> 了。假如一个 URL 要实现 <code>GET</code>、<code>POST</code>、<code>PUT</code> 三种方法,你需要在一个 view function 内去检测 <code>if method == "GET"</code> 等等,也挺麻烦。</p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Sat, 08 Nov 2014 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2014-11-08:2014/11/flask-webpy-routing/</guid><category>flask</category><category>web-develop</category><category>python</category></item><item><title>怎么设置一个网页中 点开一个链接后 其它链接不能再点击</title><link>https://shajiquan.com/2014/03/qa-frontend-js-click/</link><description><h2>原题</h2>
<ul>
<li>标题:怎么设置一个网页中 点开一个链接后 其它链接不能再点击</li>
<li>网址:http://segmentfault.com/q/1010000000434859/a-1020000000435212</li>
<li>问题详情:</li>
</ul>
<p>怎么设置一个网页中 点开一个链接后 跳转之前 页面其它链接不能再点击</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="kd">var</span> <span class="nx">url</span><span class="o">=</span><span class="k">this</span><span class="p">.</span><span class="nx">href</span><span class="p">;</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">&quot;href&quot;</span><span class="p">,</span><span class="s2">&quot;#&quot;</span><span class="p">);</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="o">=</span><span class="nx">url</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>这个咋样</p>
<hr />
<h2>解答</h2>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#Link&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">not</span><span class="p">(</span><span class="s2">&quot;#Link&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">){</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
<p>update --- 贴一下完整代码:
步骤:点击A链接,其他链接不可点击,跳转到A链接。</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">not</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)).</span><span class="nx">text</span><span class="p">(</span><span class="s2">&quot;即将不可点击&quot;</span><span class="p">);</span> <span class="c1">// 测试,改变其他 a 的 text,下面再禁用它们的点击。</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">not</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span> <span class="c1">// 禁止当前a之外的其他a的点击事件。</span>
<span class="p">});</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">href</span><span class="p">;</span> <span class="c1">// 跳转到目的地,当前a的href。</span>
<span class="p">});</span>
</pre></div>
<p>--- update again,添加一个 setTimeout 测试其他链接的点击。</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span> <span class="c1">// 取消本次事件的默认行为</span>
<span class="kd">var</span> <span class="nx">thatURL</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">&quot;href&quot;</span><span class="p">);</span> <span class="c1">// 拿到目标 URL。</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">not</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)).</span><span class="nx">text</span><span class="p">(</span><span class="s2">&quot;即将不可点击&quot;</span><span class="p">);</span> <span class="c1">// 测试,改变其他 a 的 text,下面再禁用它们的点击。</span>
<span class="nx">$</span><span class="p">(</span><span class="s2">&quot;a&quot;</span><span class="p">).</span><span class="nx">not</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span> <span class="c1">// 取消当前 a 之外的其他 a 的默认行为(点击事件)。</span>
<span class="p">});</span>
<span class="c1">// 建个函数做跳转</span>
<span class="kd">function</span> <span class="nx">redirect</span><span class="p">()</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span> <span class="o">=</span> <span class="nx">thatURL</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">setTimeout</span><span class="p">(</span><span class="nx">redirect</span><span class="p">,</span> <span class="mi">3000</span><span class="p">);</span> <span class="c1">// 延时跳转,期间可点击其他链接做测试。</span>
<span class="p">});</span>
</pre></div></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Fri, 14 Mar 2014 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2014-03-14:2014/03/qa-frontend-js-click/</guid><category>frontend</category><category>javascript</category><category>jquery</category></item><item><title>百度地图接口调用 golang 版</title><link>https://shajiquan.com/2014/01/baidu-map-api-golang/</link><description><h2>gobaidumap</h2>
<p>百度地图接口调用 golang 版。支持GEO、地址双向获取,IP获取地址。</p>
<p>外国 IP 什么的,百度不支持。</p>
<p>练习 golang 时写的,见笑啦!</p>
<p>感谢 <a href="https://github.com/zzdboy">@zzdboy</a> 的测试的反馈!</p>
<h3>安装/更新</h3>
<div class="highlight"><pre>go get -u github.com/shajiquan/gobaidumap
</pre></div>
<h3>注意</h3>
<p>请到百度地图开发者中心申请自己的 App Key,下方的 key 是百度提供的,不保证永远有效。</p>
<h3>使用</h3>
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;github.com/shajiquan/gobaidumap&quot;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">lat</span> <span class="kt">string</span> <span class="p">=</span> <span class="s">&quot;40.069462&quot;</span>
<span class="kd">var</span> <span class="nx">lng</span> <span class="kt">string</span> <span class="p">=</span> <span class="s">&quot;116.346364&quot;</span>
<span class="c1">// 从坐标到地址</span>
<span class="nx">GEOToAddress</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">baidumap</span><span class="p">.</span><span class="nx">GetAddressViaGEO</span><span class="p">(</span><span class="nx">lat</span><span class="p">,</span> <span class="nx">lng</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;坐标到地址:&quot;</span><span class="p">,</span> <span class="nx">GEOToAddress</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;坐标到地址 - 地址&quot;</span><span class="p">,</span> <span class="nx">GEOToAddress</span><span class="p">.</span><span class="nx">Result</span><span class="p">.</span><span class="nx">AddressComponent</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// 从地址到坐标</span>
<span class="nx">address</span> <span class="o">:=</span> <span class="s">&quot;百度大厦&quot;</span>
<span class="nx">addressToGEO</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">baidumap</span><span class="p">.</span><span class="nx">GetGeoViaAddress</span><span class="p">(</span><span class="nx">address</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从地址到坐标 - All&quot;</span><span class="p">,</span> <span class="nx">addressToGEO</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从地址到坐标 - Lat&quot;</span><span class="p">,</span> <span class="nx">addressToGEO</span><span class="p">.</span><span class="nx">Result</span><span class="p">.</span><span class="nx">Location</span><span class="p">.</span><span class="nx">Lat</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从地址到坐标 - Lng&quot;</span><span class="p">,</span> <span class="nx">addressToGEO</span><span class="p">.</span><span class="nx">Result</span><span class="p">.</span><span class="nx">Location</span><span class="p">.</span><span class="nx">Lng</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// 从IP到地址</span>
<span class="nx">ipAddress</span> <span class="o">:=</span> <span class="s">&quot;202.198.16.3&quot;</span>
<span class="nx">IPToAddress</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">baidumap</span><span class="p">.</span><span class="nx">GetAddressViaIP</span><span class="p">(</span><span class="nx">ipAddress</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从IP到地址:&quot;</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从IP到地址 - 地址:&quot;</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">.</span><span class="nx">Content</span><span class="p">.</span><span class="nx">Address</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// 从IP到地址</span>
<span class="nx">ipAddress</span> <span class="p">=</span> <span class="s">&quot;8.8.8.8&quot;</span>
<span class="nx">IPToAddress</span><span class="p">,</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">baidumap</span><span class="p">.</span><span class="nx">GetAddressViaIP</span><span class="p">(</span><span class="nx">ipAddress</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从IP到地址,err !=nil:&quot;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从IP到地址:&quot;</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;从IP到地址 - 地址:&quot;</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">,</span> <span class="nx">IPToAddress</span><span class="p">.</span><span class="nx">Content</span><span class="p">.</span><span class="nx">Address</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<h3>联系 &amp; 反馈</h3>
<p>shajiquan at gmail dot com</p>
<p><a href="https://github.com/shajiquan/gobaidumap/issues">https://github.com/shajiquan/gobaidumap/issues</a></p></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">shajiquan</dc:creator><pubDate>Sat, 04 Jan 2014 00:00:00 +0800</pubDate><guid>tag:shajiquan.com,2014-01-04:2014/01/baidu-map-api-golang/</guid><category>golang</category><category>baidu-map</category><category>projects</category></item></channel></rss>