Apr 2 2010

在django中把单元测试分散到多个文件中

在django中编写单元测试的时候,django默认是到应用的目录下的tests.py中查找unittest.TestCase的子类来运行测试的。这样,我们就需要把这个应用的所有测试都写在tests.py中,如果测试比较多的话,这个文件就会非常大。其实我们完全可以把测试写到其他的文件中,只要在tests.py中引用这些文件中的测试类就可以了。

比如,我们可以把所有有关Book的测试放到book_tests.py中,然后在tests.py中import这个文件中的测试类, 这样就解决掉只能在tests.py中写测试的限制了。

# tests.py
from book_tests import *

Mar 19 2010

在Django view中设置ModelChoiceField的选项

我们在使用Django中的ModelChoiceField时,可以通过queryset选项来设置这个字段对应的选项。通常这个queryset的设置都是在form中定义form类的时候来使用。其实,我们也可以在view中设置queryset,这样就给了我们更加灵活的控制。比如我们有下面的类:

class Category(models.Model):
    user = models.ForeignKey(User, related_name="categories")
    name = models.CharField(max_length=50)

class Book(models.Model):
    category = models.ForeignKey(Category)
    name = models.CharField(max_length=50)

class BookForm(form.ModelForm):
    class Meta:
        model = Book

在Book类中,把category作为一个外键,当我们使用ModelForm时,会自动使用ModelChoiceField,而这个Field的选项默认就是全部的目录。如果我们的需求是要把选项限制在当前登录用户创建的目录时,我们就需要动态来设置这个字段的选项。我们可以在view中通过下面的方式来实现:

def create_book(request):
    form = BookForm()
    form.base_fields['category'].queryset = request.user.categories.all()
    ......


Mar 5 2010

在Django中配置本地设置

在Django项目中,我们一般都会把配置信息放置在settings.py中。在一个多人的项目中,可能某些设置项每个人的配置会不相同。比如MEDIA_ROOT,没法要求每个开发人员都使用相同的路径。那当开发人员开发的时候,他就需要在不修改settings.py的情况下,来使用自己的本地配置。解决的方法就是在本地创建一个local_settings.py文件,然后在settings.py中引用这个文件。把下面的代码放到settings.py的最后:

try:
    from local_settings import *
except
    ImportError: pass

这样,把本地的设置项放置到local_settings.py中,就可以覆盖settings.py中的配置。而settings.py中可以放置部署时的设置,这样在部署时,就不需要做额外的修改。


Jan 23 2010

32 or 64, that is the question

这两天在雪豹上安装PostgreSQL和pyscopg2,差点没被折腾死。由于雪豹的内核升级到了64位并兼容32位,所以在雪豹上运行的应用程序就会有64位和32位这两种情况。而要想让Python, PostgreSQL和pyscopg2正确的运行,最根本的一点就是要让它们都以相同的方式运行。

由于PostgreSQL现在还没有提供64位的安装版本,所以也就需要Python,PostgreSQL和pyscopg2全部以32位的方式来运行。下面就是一些在安装中需要注意的地方。

1. 让Python以32位运行。雪豹上自带的Python版本为2.6.1,并且默认是以64位的方式来运行。所以,我们首先要把Python以32位的方式来运行。只要在命令行中输入下面的命令就可以了:

$ defaults write com.apple.versioner.python Prefer-32-Bit -bool yes

2. 安装PostgreSQL,这个安装当中没有特别需要注意的地方,下载下来运行安装包就可以了。

3. 安装pyscopg2。这是最麻烦的一步。首先,要修改setup.cfg中pg_config的路径。如果你在安装PostgreSQL时使用了默认安装,那pg_config的路径应该是/Library/PostgreSQL/8.4/bin/pg_config。

pg_config=/Library/PostgreSQL/8.4/bin/pg_config

修改完毕后,要用32位的方式来编译和安装pyscopg2。

ARCHFLAGS=’-arch i386′ python setup.py build

ARCHFLAGS=’-arch i386′ python setup.py install

通过上面的步骤,基本上就可以保证Python,PostgreSQL和pyscopg2能够正常工作了。

其实除了PostgreSQL和pyscopg2,在雪豹上安装Mysql和Mysqldb时,同样也会遇到这样的问题。但是Mysql的情况稍微复杂,因为Mysql有64位和32位两种版本。但是最根本的一条就是要保证这些程序都以相同的方式编译和运行就可以了。


Jan 11 2010

用户模块功能与流程

表结构

users表:用于保存用户信息。

id int(11) PrimaryKey
username varchar(32) 用户名
password char(50) 密码
name varchar(50) 名字
email varchar(127) 邮件地址
logins int(10) 登录次数
last_login timestamp 最后登录时间

user_pendings表:用户email地址验证信息。

id int(10) PrimaryKey
user_id int(10) 用户id
token char(10) 用于验证的随即字符串
created_date timestamp 创建时间

roles表:角色表。在角色表中可预先插入系统中预置的角色,如’login’角色,拥有此角色的用户可以登录到系统中。

id int(11) PrimaryKey
name varchar(30) 角色名称
description varchar(100) 描述

roles_users表:users表和roles表的多对多对应表。

role_id int(11)
user_id int(11)

功能与流程

一、 用户注册

  1. 显示用户注册界面。
  2. 用户填写注册信息,并提交。
  3. 系统通过Javascript对注册信息进行验证。包括:
    • 非空验证。像用户名、密码、email等信息不能为空。
    • 长度验证。验证数据长度是否过短或过长。
    • 两次输入的密码是否相同。
    • email地址的格式是否合法。
    • 通过Ajax验证用户名是否存在。(可选,也可以提交到后台验证)
    • 通过Ajax验证email地址是否已经被使用。(可选,可以提交到后台验证)
  4. 数据如果未通过验证,显示错误信息,并重复步骤2、3。
  5. 如果前台数据验证通过,则将数据提交到后台,进行后台数据验证。后台数据验证的方面和前台相同。
  6. 如果数据未通过后台验证,则返回用户注册页面,并显示所有的错误信息,让用户对信息进行修改。重复步骤2、3、4、5。
  7. 如果数据通过了后台验证,就将用户注册的信息保存到users表中,但是不要给这个用户添加任何角色。在添加纪录前,要将密码加密后再保存到数据库中。
  8. 用户保存完毕后,生成一个10位的随即字符串,把字符串和用户的id组合到一个url中,如http://xxx.com/user/15/verify/ad89d09uu2。把这个url发送给用户注册时使用的email地址,告知用户通过点击这个链接,就可以完成注册的认证。
  9. 发出email后,将user id和生成的这个随即字符串(token)保存到user_pendings表中。
  10. 显示注册成功页面。

二、验证用户email地址

  1. 用户点击收到的验证邮件中的验证链接。
  2. 根据url中用户的id,到user_pendings表中查找是否存在这个验证信息。如果不存在,显示验证失败页面。
  3. 如果验证信息存在,对比url中的token和这个用户在user_pendings表中的token是否相同。如果不相同,显示验证失败页面。
  4. 如果token也相同,则查看token生成的日期是否已经超过了系统规定的token失效时间,比如24小时。如果token失效,则显示验证失败页面。
  5. 如果token未过期,则将’login’角色赋给当前用户,使用户可以具有登录的权限。
  6. 将user_pendings中此用户的验证信息删除。
  7. 显示验证成功页面(或登录页面)。

三、用户登录

  1. 显示用户登录页面。
  2. 用户输入用户名和密码,点击“登录”按钮进行登录。
  3. 通过Javascript进行前台数据验证。包括:
    • 用户名和密码不能为空。
    • 用户名和密码的长度不能过长或过短。
  4. 如果前台验证失败,则显示所有错误信息,回到步骤2。
  5. 如果前台验证通过,则进入后台验证。系统通过用户输入的用户名,在users表中查找这个用户是否存在。如果不存在,则显示登录失败页面,让用户重新登录。
  6. 如果用户存在,则对比用户输入的密码是否正确。如果密码错误,显示登录失败页面,让用户重新登录。
  7. 如果密码正确,则察看此用户是否具有’login’角色。如果没有,则提示用户没有登录的权限。
  8. 如果用户有’login’的角色,则将用户信息保存到session中,并显示登录成功页面。