GraphQL+Django提供基本API

GraphQL是Facebook去年开源的一套数据查询语言,对于大型系统,GraphQL提供一种灵活的访问通用数据的方式。当时正好有一个项目,需要前端调用后台的数据(Express+Postgresql)实现图表展示,我就从Postgresql里把数据导出成JSON文件(后来用Promise改成直接查询数据库),前端直接用GraphQL获取自己需要的数据,后台就省掉了制作API、写SQL的工作,运行至今基本稳定。

当时GraphQL还没有针对Django的modules,前两个月发布了graphene-django,做的事情不多,但可以搭配其他插件例如django-filters来实现更丰富的查询。GraphQL的优势在于查询语句的通用性和易读性,相比REST架构来说时间较短还不够成熟,如果是复杂需求后台的开发量仍然不小,现阶段在生产环境用Django做一个API服务还是rest framework等成熟的方案会更好。本文实现一个针对Django自带的User Model的简单API。

环境:

Django 1.10.4
graphene-django-1.2.0

Setup

安装graphene-django,如果是新建Django项目,创建后执行migrate创建表,再创建admin用户:

编辑settings.py,将graphene-django加入INSTALLED_APPS:

再编辑urls.py,导入GraphQLView,加上graphql的设置:

执行runserver,这时候访问/graphql会报错,显示没有提供schema。

Schema

在dmyz目录中新建schema.py文件,目录结构如下:

编辑schema.py文件,导入DjangoObjectType和graphene,处理django自带的User Model,代码如下:

最后编辑settings.py,加上配置:

现在重新访问/graphql,可以看到自带的前端界面,在左上方文本框中输入:

运行(点击上方▶️按钮)返回admin用户的username和email。右侧的Docs会显示Query信息,下划线命名也会自动转成驼峰命名。

查询语句完整格式是 query 名称{},上面的查询语句省掉了query,因为GraphQL默认会作为query语句执行,如果是mutation就需要加上了。关于查询语句可以参考官方文档:http://graphql.org/learn/queries/

Schema & Type & Field

无论后台是Python还是Nodejs,查询语句都是一样的,但不同语言对Schema的实现方式不同。Schema定义数据的呈现结构,包含各种Types,其中Query和Mutation是两个特殊的Type,Type通过Fields指定返回的数据字段。以之前的代码为例,代码中定义了Type(Query)和Fields(users),指定resolve来处理数据。

Filter

先增加一个测试用户,在后台添加或者执行:

执行之前的查询语句会返回两条记录。修改schema.py的修改Query:

执行新的查询语句,指定id:

新的查询语句用逗号分隔字段,增加了名字,执行后只返回id=2的用户:

Mutation

先继承graphene.Mutation创建一个类,定义输入的参数,再处理成ObjectType传递给Schema:

查询语句必须申明是mutation,传入Input中定义的字段,还要定义返回的内容:

执行后返回数据:

Afterword

如前文提到的,GraphQL不如REST架构历史悠久,但也有自己的独特优势:一是返回结果跟查询语句相关,对于返回的结构能有清晰认识,REST请求时并不知道会返回JSON还是XML,也不知道会返回那些字段;二是数据变动更灵活,不需要像以前一样v1/v2…vn来标明版本,采用单一查询入口更容易扩展。GraphQL是React生态的一部分(还有Relay),支持上目前来看是可以保证的。

[转]谈史学论题选择

讲者:严耕望 教授

日期:一九八零年十月廿三日(星期四)

时间:五时至六时三十分

地点:新亚书院人文馆十二室

谈史学论题选择

研究历史,首要的是选择题目。就小范围说,是一篇专门论文题;放大些说,是研究范围,也可说就是:面。无论是一篇论文题或一个研究的广面,对于研究的成绩及其所发生的影响都有极大关系。关于此一问题,我想分下面几点谈论。

(一)具体问题与抽象问题

历史上的某些问题比较具体,某些问题比较抽象,当然这很难划分,但无可否认,可作大体的划分,例如就大范围说,学术思想文学艺术问题比较抽象,政治经济民族社会问题就比较具体。这其中也各有程度的不同,例如学术又比思想具体些,政制又比政事具体些。前辈学人中,如陈寅恪先生喜欢讲比较具体些的问题,少论抽象问题。这在俞大维先生写的《怀念陈寅恪先生》一文中已明白讲到。

综观陈先生的全部论著明显的有此倾向。再如陈援庵先生,更是如此。他的《中西回史日历》,不但具体,简直就是一项机械工作,其功不细!我个人也喜欢研究具体问题。我的主要工作涉及两大范围,一是政治制度,二是历史人文地理,都是具体性,少涉抽象性。

我认为研究工作,为把稳起见,最好多做具体问题,少做抽象问题。研究具体问题,用可靠史料,下深刻功夫,一定能获得可观的成绩,而且所获成绩比较容易站得住脚,不容易被人否定,也就是说较容易成为定论;但抽象问题,虽然同样用可靠史料,同样下深刻功夫,但所获成绩就不一定能站住,也就不容易成为大家都接受的定论。因为具体问题的证据也比较具体,较容易作客观的把握,需要主观判断的成份较少,但抽象问题的证据往往也比较抽象,较难作客观的把握,需要主观判断的成份较多。主观判断的成份较多,在作者本身言,就比较容易走上主观意向,作错误的判断。在读者而言,在其它的研究者而言,也各参入主观成份,有不同的认识,作不同的判断。因此人各有一是非,上焉者可成一家之言,但很难得到大家都能承认的公论。然而一般人都比较喜欢讲抽象问题,尤其现在一般青年更似有此倾向。这或许是因为对于抽象问题,容易发议论,提意见,讲起来比较可以自由发挥想象力,甚至于仅得少数数据,一知半解,也可以主观的贯连,痛快淋漓的发挥一番,满足自己丰富的发表欲,至于具体问题,总认为繁难,不易见功。但实际上,具体问题似难实易,抽象问题似易实难。因为具体问题,可以肯定的说,一分耕耘,一分收获;抽象问题,虽然原则上也是如此,但不必如此。也许自己辛苦经营,以为发千古之未覆,心满意足,但他人看来可能付之一笑。

然则大家都搁置抽象问题不予研究吗?我实并无这意。不过就一般人言,以正时弊。若是对于抽象问题实有浓厚兴趣,自信天份极高,能见人所不能见,自亦可从事抽象问题的研究。不过要特别警觉,谨慎从事。天份高,功夫深,能谨慎,所得成果,纵然不能得到公认,但若能真正一家之言,也就是一项成就。
(more…)

用django-webpack-loader实现Django和Webpack的绑定

django-webpack-loader是Django去年的热门App之一,实现Django和Webpack的绑定。做法很简洁,就是用一个nodejs模块处理Webpack的输出,Django再去读取这个模块生成的JSON文件,加载对应的bundle文件就行了。最近在cygwin里重新部署了一次,分享其中的关键点。环境是:

  • Django 1.9.5
  • NodeJS v6.0.0
  • Win7(64)+Cygwin2.4.1

场景是将现有的一个Django项目,转成用Webpack来处理静态文件。因为没有执行npm init,安装时会提示找不到package.json。使用Webpack的人应该都知道自己在干什么,所以一些常见的基础配置、错误提示等本文不会涉及。

Install & Settings

首先用npm/pip安装相关的包:

然后设置Django(settings.py),把webpack_loader加到INSTALLED_APPS中,指定templates和static目录,新增WEBPACK_LOADER:

这样Django会从/static/js/dist/读取Webpack生成的文件。接下来配置Webpack,在目录中新建webpack.config.js,内容如下:

Usage

在当前目录执行webpack(全局或是项目),会自动读取/static/js/src/index.js,生成/static/js/dist/main.dev.js。当然,现在会报错提示找不到entry,要创建对应的js文件,以下只写了import语句来验证loader已经加载:

执行后在dist中生成js文件。现在要自动把生成的文件(bundle)加载到模板,django-webpack-loader使用template tag的方式来实现。创建一个模板文件,内容为:

这样生成的js文件就会以script标签的形式自动插入当前模板了。Webpack执行的结果(通过webpack-bundle-tracker)会写入webpack-stats.json文件中,Django运行时会读取这个json文件,如果出错会抛出500错误。

Extension

render_bundle也接受参数来指定文件扩展,可以处理css文件。例如要在Django中使用AdminLET,执行以下步骤可以通过Webpack来加载:

上列命令安装AdminLET和需要的loader,因为css文件中通常都会指定图片文件(还是字体等),所以还需要url-loader/file-loader。extract-text-webpack-plugin用来把css合并到一个文件中。

修改webpack.config.js

最后修改/static/js/src/index.js文件和模板文件:

可以看到按钮已经应用了样式。

Python读取Outlook的日历

公司的会议预订系统使用Outlook,要读取这些预订记录传到部署在阿里云的数据库。Exchange服务器没办法从外网访问,就在内网某台机器上写了一个脚本,定时执行,来从Outlook中读取日历上的预订记录。

模块:pywin32 (http://sourceforge.net/projects/pywin32/)
环境:Windows 2008 + Outlook 2013 + Python 2.7.8

Filder & Items

因为从来没做过Windows开发,所以先看了一遍文档,主要的概念是Folder(https://msdn.microsoft.com/EN-US/library/ff866772.aspx)。

Folders

所以其实就是要读取Outlook中名为Calendar的Folder,要获得会议预订记录,取出Folder的Items进行迭代就可以了:

(more…)

Linux设置iBeacon支持微信摇一摇

今年微信的摇一摇开始支持iBeacon了,淘宝上冒出一堆卖iBeacon基站的店铺,价格也比之前便宜许多。只是在开发测试阶段,直接用现有的设备会更简单,手头有一个USB蓝牙适配器,于是用Linux机器改造成iBeacon基站了,本文记录设置的步骤。前两年iBeacon刚发布的时候,有篇很火的文章指导如何用Raspberry搭建iBeacon基站(DIY Beacon with a Raspberry Pi),本文有参考那篇文章,只想实现iBeacon基站,不关注微信设置,也建议直接看原文。

蓝牙设备需要支持BLE(Bluetooth Low Energy,低功耗蓝牙)且是4.0版,我买的这个是CSR8510芯片,淘宝价格30元以内。以下设置在Ubuntu 14.04,Openwrt(ZTE Q7+r47026)和Raspbian(cb799af)中测试通过。一些APP(例如beacon-toolkit)和脚本(例如linux-ibeacon)可以简化配置。

微信设置

首页进入微信摇一摇后台(https://zb.weixin.qq.com/nearby/index.xhtml),点击左侧『页面管理』进入页面点击,点击『添加页面』按钮新增一个页面,跳转到dmyz.org:
Add page

(more…)

React.js最佳实践

虽然标题是最佳实践,其实是这一年来自己挖的各种坑,填了之后发现“其实这样写就不会有坑了”的总结…环境为桌面浏览器,因为目前后端还是Python为主,暂时没机会在NodeJS中使用各种便利的特征/插件。

代码顺序

定义一个React组件通常是包含以下代码:

以空行分割,有4个部分:

(more…)

关于中国色网站的说明

很早之前在一个日本网站上看过一个很不错的颜色排版方式,于是做了一个中国版的http://zhongguose.com/。我个人不认为山寨是什么丢人的事(企鹅可恨在于抢人饭碗而不在于山寨),直接在右下角注明了。完工后就任其自生自灭,也没太关注。结果前段时间在微博上被转发后,当天访问量突然飙升到10w级,随之而来相关讨论和邮件(怎么就没人捐钱呢╮(╯_╰)╭),有鼓励有质疑,故在此统一回应。

先说容易懂的,关于颜色数值和名字。前人研究请参看:《色譜》與《中國的傳統色》、《中國色名綜覽》之色名比較研究。数值是从《色谱》和其他书上取的。其中标注星号的例如天青,出处为东方出版社2013年版的《中国颜色》,这本书算不上权威,FB上有读者质疑它使用了曾启熊教授的研究而没有注明,所以只取了这书上很少的几种颜色作为补充。

通常来说,礼仪的场合古人倾向使用纯度很高颜色(肖世孟. 先秦色彩研究[D]. 武汉大学 2011),这些颜色在现代印刷、显示的场景中就太重了。因此经典的五色——青、赤、黄、白、黑——没有单独列出来,名字直白或者生活中常见的颜色也没有选入(例如大红、灰白)。一言蔽之就是有缺漏但不会有冗余,只取前人研究过有据可查的而不去自己臆造。

我的本业是Web开发,色彩研究我是外行,如果有更好的数据来源或是更权威的颜色数值请告知,我会及时更新的。

然后说说网站。网站13年就完工了,那时代码里还充斥着-webkit-的写法,这两年HTML5规范确定后就用新的方式重写了,除IE这种不支持mask的奇怪浏览器,其他浏览器都能正常浏览。功能不复杂,没有使用jQuery之类的DOM框架,react那些视图绑定的框架就更用不上了。也考虑过是否基于它来扩展社区类的功能,但没有更好的想法前还是保持现状了。个人最希望出现一位有爱的设计师,做一个更中式风格的设计。一来可以去掉右下角的Shanzai标注,二来实现一个国内的漂亮网站,在这个被微信拉底了整体设计风格,充斥着华而不实Campaign网站的大环境中,总是一个很好的示范吧。

最后的重点,感谢所有给我建议、鼓励,喜欢这个网站的网友们!

Python,Javascript(NodeJS),PHP之间的AES加密解密

场景是现有的几个项目,微信企业号是PHP,广告数据处理平台是Python,其中的Web API部分是NodeJS。现在这几个应用之间要传递数据,基于安全考虑先用AES加密,接收后做解密处理。本来预想是一个很简单的工作,库都是现成的,但发现网上的代码要么是不全,要么是padding处理不一致,所以最后还是自己看文档来写的,分享其中的核心代码,有类似需求可以直接拿去用。

AES

AES的介绍可以参看Wikipedia: 高级加密标准。这种加密方式需要指定Key(密钥)和IV(初始化向量),解密时使用同样的Key和IV进行解密。其次需要padding(填充字符),网上一些代码是用空格或者大括号做padding,解密后再用rstrip/rtrim/replace清掉,但用标准的PKCS会更好。

(more…)

Django+MySQL安装配置详解(Linux)[更新为1.8.2版]

Perface

Django是一个开源的Web应用框架,由Python写成,并于2005年7月在BSD许可证下发布。Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django采用MVC设计模式注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。本文介绍Django在Linux(Ubuntu 14.04.2)+MySQL(5.5.43)环境下安装、配置的过程,包括安装、运行、添加应用的所有流程,最终建立一个可以从MySQL读取文章并显示的Django应用。文章面向刚接触Python/Django的初学者,所以安装过程都以默认环境为主,用pip可以简化安装过程。

Install

首先下载Django,得到Django-1.8.2.tar.gz,后解压并安装

$ wget https://www.djangoproject.com/m/releases/1.8/Django-1.8.2.tar.gz
$ tar xzvf Django-1.8.2.tar.gz
$ cd Django-1.8.2
$ sudo python setup.py install

如果提示缺少setuptools还要下载安装setuptools(建议提前安上,因为在安装MySQL for Python的时候也会用到)。
(more…)

重新学习HTML5的HTML

经过媒体的渲染,目前大众认为的HTML5大致等于:酷炫的效果,复杂的技术,手机能正常浏览的网页。于是经常有人问我:某个功能,某个效果,HTML5能实现吗?这种表现层的问题,如果排除平台因素回答就是:以前实现不了的,HTML5还是实现不了;以前能实现的,HTML5通常能实现得更好。比如通知,以前用轮询,现在可以用websocket;比如想直接读取客户Windows目录下的文件(…),现在(正常情况下)还是实现不了…

广义的HTML5是一系列技术组合,希望能减少浏览器对插件(Flash/Silverlight/JAVA)的依赖。于是大家关注的重点主要是各种新增的API,HTML作为一种标记语法就没太重视。结果当我用canvas做好表格,用localStorage实现缓存,用video+websocket改进了视频播放后,回头来看我写的HTML代码其实还不够规范。

所以这篇文章是关于HTML的,内容顺序按照HTML的顺序:从doctype到metadata,然后是部分常见标签,总之都是非常浅显的内容。嵌入内容的标签(例如img/object/video)不在讨论的范围,跟CSS或JS关联太紧密的标签(例如各种事件绑定和output标签)也不会涉及。全文没有截图,很多HTML代码是直接写在页面上的,Firefox/Chrome测试正常,但我没办法控制您的浏览器以及爬虫,因此如果样式出现误差请更换浏览器或找找原文链接…

(more…)