标签归档:django

开始写lbworkflow的文档

文档是一个开源项目很重要的一个组成部分,在我看来一个没有文档的开源项目不是一个合格的项目。最近开始给 django-lb-workflow 写文档。

对我来说喜欢写代码多过写文档,特别是在我英文不灵光的情况下。工作流本身就是一个挺复杂的东西,也不知道最终写出来的文档别人能不能看懂。

目前文档只完成了很小的一部分。里面有一个简单的例子,照葫芦画瓢应当也基本能知道怎么使用了。
文档地址: http://django-lb-workflow.rtfd.io/

lbworkflow预览版

django-lb-workflow 是我开发的一个工作流组件。目前还有很多工作要做,不过主体功能已基本可以使用了。在我看来还远没有到可以发布的阶段,不过还是很想先宣传一下,也希望能收到一些反馈。

关于为啥要挖这个坑,以及一下想法可以见之前的博客: 挖了一个新坑-Django的工作流引擎

演示项目地址:
http://wf.haoluobo.com/
管理员用户:
用户名:admin 密码:password
登陆后快速切换用户:
http://wf.haoluobo.com/impersonate/search/
http://wf.haoluobo.com/impersonate/stop/
流程配置信息查看:
http://wf.haoluobo.com/admin/lbworkflow/

目前还处于零文档的情况,用法只能先看代码了。
测试用例里是一个请假的演示:
https://github.com/vicalloy/django-lb-workflow/tree/master/lbworkflow/tests/leave

最好的技术构架

最近看到一篇文章,里面谈通过Java替换之前的Python实现使服务的响应速度得到了很大的提升。同时又看到有公司通过Go替换Scala,取得了不错的效果。

似乎是Go>Java>Python?显然不是。

在项目启动的初期你很难预计到自己的项目最终将长成什么样子,最终能达到多大的规模。你能做的只是给出一个较清晰的中短期规划以及一个较模糊的长期规划。然后思考如何在满足要求的情况下尽快的把东西做出来。毕竟事情不会不完全按照你的预期发展,看上去在完美的构架也不可能一直完美下去。根据需求持续的演进才是正道。

关于性能:

由于需要服务海量用户,因此在提到互联网应用的时候很多人都对高性能有着异常的执着。经常听到有人说XX语言慢,XX框架慢。但实际上脱离了需求和构架单纯谈的语言/框架性能是没有意义的。就如Instagram至今依旧用着以慢著称的Django(注:其实我也挺好奇为啥没有将Django换掉。按照我的理解Django的有点是功能及资源丰富,性能方面确实没啥优势。按说Instagram对Web框架的功能需求应当非常少,换个更轻量高效的似乎会更好些?)。

另外优化的成本实际上也挺高,在早期用户不多的时候对性能的优化或许还不如直接加硬件来的实惠。

目前项目用的一些东西

项目基于Django构建,如果你们也在用Django,可以参考下。

源代码管理 HG

之所以用HG完全是因为公司代码库用的是HG,如果让我选当然更愿意用Git。大多情况下HG也已经够用了。
项目中开发的Python公共模块使用submodule的方式引入。采用submodule的方式对子模块的更改和更新都会比较方便。

JS等静态资源管理 Bower

作为一个Web项目自然少不了用到jQuery等第三方JS库。将这些第三方库全部下回来丢到代码库里一是让代码库变的不必要的臃肿,另一方面库之间的依赖关系也不容易管理。引入Bower后代码库要干净很多。

Web前端框架 Bootstrap

现在用Bootstrap的网站有些太多了,以至于Bootstrap让人有些审美疲劳,不过对于缺少专业前端的团队来说Bootstrap绝对是个利器。

JS/CSS压缩 django-compressor

使用django-compressor可以对JS/CSS进行压缩,加快网站加载速度。

表单 crispy_forms

如果是做互联网应用crispy_forms的作用可能不大,但是对管理后台来说crispy_forms非常棒。

django-impersonate

让你可以方便的切换成其他用户。在系统维护的时候会方便很多。

异常日志 Sentry

Sentry 是一个实时的事件日志和聚合平台,基于 Django 构建。Sentry可以将程序的所有异常自动记录下来,然后在一个好用的 UI 上呈现和搜索。如果你还没用过Sentry,强烈推荐一定要试试。

为什么没有用

  • React/Angular
    • 我们的应用场景还是传统的WEB应用,React/Angular可能更适合Web APP的场景,应用起来可能不能带来太多的便利性。
  • Webpack
    • Webpack 是当下最热门的前端资源模块化管理和打包工具。也曾想试试,不过我们这里前端部分还不算太复杂,冒然引入Webpack似乎也不是太必要。目前Bower+django-compressor已可以较好的满足我们的需求了。

django-lbutils

在Github上公开了不少项目,不过其中大多都算不上“开源”。在我看来开源也应当是一件认真的事情,需要对项目持续的维护,同时也需要提供必要测试用例及文档以保证项目的质量。
最近打算将自用的Django工具组件做个简单的整理然后发布了。为了让项目不要太“随意”,开始补测试用例及文档。因为是自用,测试用例和文档几乎为零。最初只是想简单的修葺,不想真正做起来工作比预期的要高出很多。整了许久代码中的注释依旧很不全,测试的覆盖率都还未达到80%,文档更是没开始动。因为文档还没弄完,所以项目也不算正式发布,如果你感兴趣可以先去看看django-lbutils
为了这个项目,尝试了一些之前经常看到却一直没怎么使用过的工具。

Tox

Tox是一个Python的自动打包测试用具,用来测试Python库在不同环境下的兼容性。因为是自用,本机环境跑起来是没啥问题。不过在兼容性测试时部分测试用例在Python3以及Django的某些版本下跑起来会有问题。为了搞定兼容性花费了不少时间。

Travis CI

Travis CI是一个在线的持续构建平台。Travis CI会检查你在Github上项目的变化,每当有新push的时候进行自动编译。我现在是每次改动后,直接在Travis CI看测试用例的执行情况。

Coveralls

Coveralls测试覆盖率查看工具。结合Travis CI,可在每次测试完成后将测试覆盖率信息推送到Coveralls。在Coveralls可方便查看当前的测试覆盖率。

Read the Docs

Read the Docs文档托管服务。可从Github抓取文档并自动编译好生成在线文档,目前几乎所有的Python库都将文档托管在上面。

[django-ajax-validation]Django表单AJAX校验及提交的APP

项目地址https://github.com/vicalloy/django-ajax-validation
django-ajax-validation是一个使Django支持表单AJAX校验的第三方APP。我做了一些修改,增加了表单的AJAX提交以及twitter-bootstrap的支持。

安装

  • pip install git+git://github.com/vicalloy/django-ajax-validation.git
  • 在Django settings的INSTALLED_APPS中加上”ajax_validation”。

一个简单的使用范例

views.py

from ajax_validation.views import validate_form
from ajax_validation.utils import render_json_response
...
class TimelineForm(forms.ModelForm):
    class Meta:
        model = Book
def add_book(request):
    #创建表单并进行校验。返回表单以及校验结果。
    form, validate = validate_form(request, form_class=BookForm)
    if validate['valid']:#如果校验成功,执行保持操作
        book = form.save()
    return render_json_response(validate)//返回JSON

模板

进阶

django-ajax-validation的原始文档就写的非常糟糕,我也偷懒,所以想了解更多还是直接看代码吧。

SAE Storage for Django

DPress 修正后想着要部署一个在线的演示程序。问题是我自己虚拟主机的资源已经捉襟见肘,于是只能打SAE的主意了。
为保证文件上传功能的正常使用需要将Django默认的Storage实现替换为SAE的storage实现。SAE的官方并没有提供Django的storage实现,需要自己另外实现。在github:gist上有人贴出了SAE Storage for Django的实现(SAE Storage for Django)。github:gist上的这个SAE Storage实现有些bug,我修正后的版本见saestorage
注:

  • SAE Storage单节点的最大容量为2G(注:SAE Storage 服务限制)。这对于一些小站点来说是没什么问题,但如果是一个大型的商业站点这必然会有些不便。难道你需要配置一个storage列表,让程序自行去寻找可用的storage?
  • SAE Storage似乎不太稳定,上传的文件经常会打不开。

“DPress”原地满血复活

GitHub地址: DPress(GitHub)
演示地址: DPress(SAE)

DPress 是我在2009用django写的一个博客系统。此后年久失修,已经跑不起来了。
这两天花了些时间将项目重新修整一下,现在项目又可以重新跑起来了。功能方面新版的DPress有了些变化。

  • 提供对 Markdown 的支持(也只支持Markdown)。
  • 使用 EpicEditor 实现Markdown的实时预览。
  • 使用 DISQUS 实现文章的评论功能。(注:既然已经有了这么好用的评论服务,为什么还要自己写代码呢)
  • 支持代码高亮度。相关的语法说明见:Fenced Code Blocks
  • 支持Tag
  • 支持RSS
  • 使用 Django FileBrowser 提供文件上传的支持。
  • 使用 flatpages 提供对About等自定义页面的管理。
  • 内置GOOGLE ANALYTICS的支持
  • 代码量非常的小
  • 模板和代码分离的比较清晰,要创建一套自己的模板会是一件比较容易的事。

已知bug:直接从网页复制文本时EpicEditor的编辑框内会自动的添加一些看不见的html标签,将导致文本显示不正常。需要粘贴文本时最好先将文本粘贴到写字板中,再重新复制粘贴。

CSRF(Cross-site request forgery)以及django中的处理方法

CSRF(Cross-site request forgery) 中文名是跨站请求伪造。
简单的说是用户访问了安全的网站A(比如支付宝)并登录,之后用户又访问了问题网站B。网站B包含恶意代码,在访问网站B的时候,网站B的网页偷偷的向网站A发起post(get)请求进行转账操作。由于你已经登录过网站A,网站A误以为请求是用户自己发起的安全请求。在操作成功后你的钱啥的也不见了。
当前Django的处理方法:
在用户访问网站时为用户生成一个CSRF防范用的token并将token保存到cookie中。每次用户发起请求时需要将token的值作为表单字段一同提交。服务端对用户提交的token值同cookie中的token进行比较,如果相同则认为安全。
由于浏览器对cookie的访问有严格的限制,问题网站B无法访问到网站A的cookie无法正确的设置token。

django的js/css压缩组件Django Compressor

为了加快网站的加载速度,我们通常要多js和css进行压缩处理。这些js和css的压缩工作如果都手动处理,费时费力。
Django Compressor 可以实现js/css的自动压缩。Django Compressor在易用性方面做的非常好,按照 文档 做简单的设置后就可以正常工作。强烈建议大家去将文档完整的看一遍(文档很短)。
使用的时候,只需要将css/js放到 compress 标签中 Django Compressor 即可自动进行处理。在debug模式时, Django Compressor 不会对做任何处理。在非debug模式时,Django Compressor会自动对js/css进行压缩,并将压缩后的问题输出到django的 STATIC_ROOT 目录。所以请务必保证 STATIC_ROOT 目录进行了正确的设置。

{% load compress %}
{% compress  [ [block_name]] %}

{% endcompress %}
{% compress css %}

{% endcompress %}

coffeescript、less 支持

在开发阶段coffeescript和less可以直接使用js来处理,在正式发布时处于加载速度的考虑需要预先编译成js和css。 Django Compressor 提供 COMPRESS_PRECOMPILERS 设置,根据type类型进行预处理。

COMPRESS_PRECOMPILERS = (
    ('text/coffeescript', 'coffee --compile --stdio'),
    ('text/less', 'lessc {infile} {outfile}'),
    ('text/x-sass', 'sass {infile} {outfile}'),
    ('text/x-scss', 'sass --scss {infile} {outfile}'),
)