• Django中文

    by{ guangboo }, published {2010-01-29}, Tag { Django / }

    使用DJANGO+MYSQL做DEMO的时候,我创建了一个Model:

     

    class Tag(models.Model):
        name = models.CharField(max_length = 100, db_index = True, unique = True)
        parent = models.ForeignKey('self', blank = True, null=True)
        active = models.BooleanField(default = True)
        
        def __unicode__(self):
            return self.name

     

    该model显然没有什么编码的问题,因为我之前有过同样的model,而且运行正常。

    现在出现的问题是,在HTML页面中可以正常显示中文,而且在admin后台Tag列表里面也显示正常,但在编辑的时候,就出现了:

    parent没有select控件的问题。如图:

    django-mysql-collation

    而且点击删除会出现“

    DjangoUnicodeDecodeError at /admin/autoworks/tag/4/delete/

    'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128). You passed in <Tag: [Bad Unicode data]> (<class 'autowords.autoworks.models.Tag'>)

    ”的异常。

    就此判断可以得出应该是self.name的编码问题。可是一起同样的情况都是正常运行的啊,现在唯一没有检查的地方就是mysql数据库里,在创建数据的时候的编码是utf-8的,我原来正常的应用的mysql数据库的编码一样的啊,就是collation,排序规则不同,这里是utf8_bin,我改成utf8_generial_ci后就正常了。

  • 配置安装Nginx+Django

    by{ guangboo }, published {2010-01-27}, Tag { Django / nginx / }

     

    user  apache apache;
    
    worker_processes  2;
    
    error_log /var/log/nginx/error_log info;
    
    events {
            worker_connections  1024;
            use epoll;
    }
    
    http {
            include                /etc/nginx/mime.types;
            default_type        application/octet-stream;
    
            log_format main
                    '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$gzip_ratio"';
    
            client_header_timeout        10m;
            client_body_timeout        10m;
            send_timeout                10m;
    
            connection_pool_size                256;
            client_header_buffer_size        1k;
            large_client_header_buffers        4 2k;
            request_pool_size                4k;
    
            gzip on;
            gzip_min_length        1100;
            gzip_buffers        4 8k;
            gzip_types        text/plain;
    
            output_buffers        1 32k;
            postpone_output        1460;
    
            sendfile        on;
            tcp_nopush        on;
            tcp_nodelay        on;
    
            keepalive_timeout        75 20;
    
            ignore_invalid_headers        on;
            index index.html;
    
            server {
                    listen 80;
                    server_name localhost;
                    # site_media - folder in uri for static files
                    location /site_media  {
                            root /path/to/media/folder;
                            }
    location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov) {
      access_log   off; # po co mi logi obrazków :)
      expires      30d;
    }
                    location / {
                            # host and port to fastcgi server
                            fastcgi_pass 127.0.0.1:8080;
                            fastcgi_param PATH_INFO $fastcgi_script_name;
                            fastcgi_param REQUEST_METHOD $request_method;
                            fastcgi_param QUERY_STRING $query_string;
                            fastcgi_param CONTENT_TYPE $content_type;
                            fastcgi_param CONTENT_LENGTH $content_length;
                            fastcgi_pass_header Authorization;
                            fastcgi_intercept_errors off;
                            }
                    access_log        /var/log/nginx/localhost.access_log main;
                    error_log        /var/log/nginx/localhost.error_log;
                    }
            }
    }

     

    特别解释一下这段代码:

    server_name localhost;  #伺服器访问地址
    # site_media - folder in uri for static files -
    location /site_media  {  #访问地址:http://host/site_media
            root /path/to/media/folder;  #web根目录
            }
    


    然后需要制作启动django的脚本,或是手动启动:

    python manage.py runfcgi host=127.0.0.1 port=8080
    --settings=settings  #意思是说,以cgi的方式启动django,地址127.0.0.1,端口8080

    最后需要启动nginx

    sbin/nginx



    然后你就可以访问你的web了,http://localhost/web_media/

    看看是否出现了django欢迎的画面呢,呵呵

    参考:http://www.rkblog.rk.edu.pl/w/p/django-nginx/

     

  • Dreamhost部署Django

    by{ guangboo }, published {2009-11-04}, Tag { Dreamhost / Django / }

    1 前言

    2 准备工作

    首先你至少应该有个在淘宝上购买的10多元一年的DreamHost合租空间,当然如果银子充裕弄一个500G+独立IP的空间更好。在DreamHost的控制面板添加一个二级域名,丑鑫鑫使用的是django.v44.cn,保存前一定要勾选中 FastCGI Support。然后就是远程连接工具,我在这里推荐Putty+WinSCP组合,

    3 开始安装

    3.1 升级python到2.5.2

    用Putty登录到DreamHost的Shell控制台执行如下的命令:

    $>mkdir opt

    $>cd opt

    $>mkdir packages

    $>wget http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tgz

    $>tar -xzvf Python-2.5.2.tgz

    第一步为创建 opt目录,第二步在opt目录下创建 packages目录,第三步到python官方网站下载Python-2.5.2源码发布包,第四步将发布包解压到Python-2.5.2目录下。

     

    $>./configure -prefix=$HOME/opt

    $>make

    $>make install

    以上步骤是编译并安装Python2.5.2

    $>cd $HOME

    $>vi .bash_profile

    编辑.bash_profile文件加入

    export PATH=$HOME/opt/bin/:$PATH

    将python加入到shell path中

    $>source .bash_profile

    刷新环境变量,确保当前执行环境使用的我们安装的最新python

    3.2 安装python-Mysql

    $>cd downloads

    $>wget http://internap.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.2.tar.gz

    $>tar xvzf MySQL-python-1.2.2.tar.gz

    $>cd MySQL-python-1.2.2

    $>python setup.py install

    3.3 安装django-1.0

    $>cd $HOME/packages

    $>wget http://www.djangoproject.com/download/1.0/tarball/

    $>tar -xzvf Django-1.0.tar.gz

    $>cd Django-1.0

    $>python setup.py install

    然后,

    在python交互环境下查看django的版本,以测试安装配置的准确性。

    >>>import django

    >>>django.VERSION

    (1, 0, ‘final’)

    OK,Succeed!

    3.4配置FastCGI

    $>cd $HOME/django

    $>wget http://svn.saddi.com/py-lib/trunk/fcgi.py

    $>chmod 755 fcgi.py

    转到先前准备的二级域名指定的目录下,下载fcgi.py,更改其权限为755,创建名为dispatch.fcgi 文件,编辑这个文件为

    #!/home/yourusername/opt/bin/python

    import sys

    sys.path += ['/home/yourusername/django_projects']

    from fcgi import WSGIServer

    from django.core.handlers.wsgi import WSGIHandler

    import os

    os.environ['DJANGO_SETTINGS_MODULE'] = ‘django1.settings’

    WSGIServer(WSGIHandler()).run()

    创建.htaccess文件内容如下:

    RewriteEngine On

    RewriteBase /

    RewriteRule ^(media/.*)$ - [L]

    RewriteRule ^(admin_media/.*)$ - [L]

    RewriteRule ^(dispatch.fcgi/.*)$ - [L]

    RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]

    用来开启apache的mod_rewrite

    最后用命令测试:

    $>./dispatch.fcgi

    如果返回的是一个django页面的字符串。

    再通过浏览器访问http://django.v44.cn

    出现的django提示

    恭喜你,配置成功。

    4 注意事项

    一定要保证dispatch.fcgi是被我们安装的最新的python解析器所执行。否则fastcgi进程将会被DreamHost的扫描进程Kill。还有就是分发文件dispatch.fcgi必须为这个文件名否则也是一样的下场。

    FastCGI: incomplete headers

    5 参考资料

    http://wiki.dreamhost.com/Python_FastCGI

    http://jeffcroft.com/blog/2006/may/11/django-dreamhost/

    http://blog.localkinegrinds.com/2007/08/20/custom-python-installation-for-django-on-dreamhost/

     

  • 批处理文件开启Mysql服务

    by{ guangboo }, published {2009-08-23}, Tag { Django / MySQL / }
    @echo off
    
    @ECHO Starting MySQL Service
    
    sc config MySQL start=demand password=guangboo
    sc start MySQL
    
    @ECHO ========================================
    
    @ECHO == Start MySQL Service Successfully!  ==
    
    @ECHO ========================================
    @ECHO Starting Klipdas app.
    
    cd "C:\Documents and Settings\Administrator\klipdas"
    manage.py runserver 8080

    打开记事本,输入上面的代码,保存为.bat文件。双击就会允许了:该批处理文件用户将mysql服务设为手动,然后启动该服务;之后再使用DOS命令进入C:\Documents and Settings\Administrator\klipdas目录,允许manage.py runserver 8080命令,就是开启klipdas应用的django测试服务器。

    这样就不用每次要打开mysql服务,然后在命令行里敲这些代码了

    cd "C:\Documents and Settings\Administrator\klipdas"
    manage.py runserver 8080

    批处理文件开启MySQL服务 运行结果截图

  • 6种流行的Web框架性能测试,Django遥遥领先

    by{ guangboo }, published {2009-08-11}, Tag { Python / Django / 性能 优化 / web应用 / }

    原文地址:http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/

    原文对六种流行的WEB开发框架进行了简单的性能测试,比较的标准首先是大流量下的稳定性,其次是性能。测试的方法很简单,页面只输出一个Hello world字符串,不涉及任何数据库操作,否则整个网站的性能就会因为数据库的影响而趋向于集中。

    测试用的硬件和系统:
    CPU: AMD OpteronT Processor 146 (2 GHz)
    Memory: 2 GB
    OS: Debian 3.1 (Linux 2.6.14)
    Web-Server: nginx/0.5.5

    测试软件:
    Siege 2.65 http://www.joedog.org/JoeDog/Siege
    Http_load 12.03.2006 http://www.acme.com/software/http_load/
    ab 2.0.41-dev Rev: 1.141

    这套硬件和软件系统应该说还是相当有代表性的,所以其结果很值得参考。具体的测试参数和测试细节还有结果的详细数字和图标可以到原文链接去看,这里只讲一下最终的结果。

    第一名:Django 占用CPU最少,性能超过第二名好几倍,使用threaded模式比prefork模式要快15%左右,(在一个中国的作者的测试情况下,threaded模式比prefork模式快近十倍),但是在高负载的情况下,threaded模式会死掉,而且无法自动重启,必须手工重启WEB 服务器,这对于生产环境服务器是不可接受的。另外,使用Psyco来加速的话,两种方式下速度都可以提高20%左右,但是内存占用量会增加1-3倍,如果硬件资源没问题,就可以考虑这种方式。

    第二名和第三名分别是TurboGears和RoR 1.1.6,它们速度差不多,但是不同负载量下的表现不同。
    RoR 1.2.1的速度比1.1.6要慢2-4倍,而且在高负载下CPU占用也大一倍。

    PHP的框架速度是最慢的,比Django慢了35倍。但是在加载了eAccelerator加速器以后速度有大幅提升,只比Django慢两倍了。

    作者后来又做了一次额外测试,增加了几个新兴的框架,但是最终结果并没有变,还是证明Django是最佳选择。而且,Python非常容易上手。另外,同样基于Python的框架Pylons也不错。

  • 自定义评论框架 Custom Comments Framework

    by{ guangboo }, published {2009-08-06}, Tag { Django / }

    django,django comment framework

    如果内置的comment framework不能满足你的需要,你可以自己添加数据和逻辑来扩展comment app的行为。comments framework允许你扩展内置的comment model,comment form,及各种comment view.

    COMMENTS_APP的配置就是在你自定义的时候使用的,将要使用自定义行为的应用的名称设置在COMMENTS_APP中,语法和INSTALLED_APPS一样,并且应用的名称也必INSTALLED_APPS的列表中。

    示例,如创建my_comment_app的应用,可以使用如下配置:

      INSTALLED_APPS = 
      ...
      'my_comment_app',
      ...
      ]
    
    COMMENTS_APP = 'my_comment_app'
    

    COMMENTS_APP列表中的应用,通过定义应用程序的__init__.py中的模块级函数来提供自定义行为。这些函数的完整列表将在下面看到,首先看一个小示例。

    custom comments app 示例

    最典型的自定义就是修改内置comment model的字段,例如,有些允许评论的网站希望评论者提供评论的标题,内置的comment model没有提供title字段。

    为实现这个目的,需要三步:

    1. 创建自定义comment model,添加title字段
    2. 创建自定义表单,同样要有title字段
    3. 在COMMENTS_APP中的应用程序中定义一些函数,将这些类通知给django。

    因此,对于上面的示例,生成my_comments_app的目录结构:

      my_comments_app/
      	__init__.py
      	models.py
      	forms.py
      

    在models.py中定义,CommentWithTitle模型:

      from django.db import models
      from django.contrib.comments.models import Comment
      class CommentWithTitle(Comment):
      	title = models.CharField(max_length=300)
      

    大部分的comment model都是Comment model的子类,然而,如果你想删除或修改Comment model中已有的字段,又不想重写模板的话,你可以试试从BaseCommentAbstractModel继承。

    下一步,在forms.py中定义comment form,更棘手一点的是:必须要创建form,并重写CommentForm.get_comment_model()和CommentForm.get_comment_create_data(),并返回包含自定义title字段的数据:

    from django import forms
    from django.contrib.comments.forms import CommentForm
    from my_comment_app.models import CommentWithTitle
      
    class CommentFormWithTitle(CommentForm):
       	title = forms.CharField(max_length=300)
       	def get_comment_model(self):
       		# Use our custom comment model instead of the built-in one.
       		return CommentWithTitle
    	def get_comment_create_data(self):
      		# Use the data of the superclass, and add in the title field
      		data = super(CommentFormWithTitle, self).get_comment_create_data()
      		data['title'] = self.cleaned_data['title']
      		return data
    

    django 提供了两个helper类,使得更容易的编写某些类别的自定义comment form;查看django.contrib.comments.forms了解更多。

    最后,在my_comments_app/__init__.py中定义两个方法,将创建的类通知给django

    from my_comments_app.models import CommentWithTitle
    from my_comments_app.forms import CommentFormWithTitle
    
    def get_model():
          return CommentWithTitle
    def get_form():
          return CommentFormWithTitle
    

    以上应该是最普通的情况,要了解更高级的应用,下节会介绍,同样可以自定义的附加方法。

    custom comment API

    django.contrib.comments应用定义一下方法;任何custom comment app都必须定义至少一个方法。虽然,所有的方法都是可选的。

    get_model()

    返回Modle评论使用的类,该类应该继承至django.contrib.comments.models.BaseCommentAbstractModel,它定义了必要的核心字段。
    默认是返回django.contrib.comments.models.Comment的实例。

    get_form()

    返回Form类,该类是你用来创建,验证,保存comment model的表单类。custom comment form应该介绍一个附加参数,target_object,它是评论的对象。
    默认返回django.contrib.comments.forms.CommentForm的实例。

    注意:默认的comment form还包含多个不引人注意的垃圾信息过滤特性(查看Notes on the comment form)。如果被自定义的表单替换的话,你可能希望看看内置表单的源码,考虑类型的功能。

    get_form_target()

    返回提交评论的URL,这就是渲染comment form时的表单action属性。默认返回URL配置中指向post_comment()视图的URL配置的实例。

    注意:如果你提供了custom comment model或者form,或两者都有,但你想使用默认的post_comment()视图,你就需要知道,Model和form必须要包含的某些附加属性和方法:查看post_comment()视图文档了解详情。

    get_flat_url()

    返回flat this comment视图的URL。
    默认返回指向django.contrib.comments.views.moderation.flag() 视图的URL实例。

    get_delete_url()

    返回delete this comemnt视图的URL
    默认返回指向django.contrib.comments.views.moderation.delete() 视图的URL实例。

    get_approve_url()

    返回approve this comment form moderation视图的URL
    默认返回指向django.contrib.comments.views.moderation.approve() view视图的URL实例。