agon-python

Posts Tagged ‘python’

Django添加自定义TEMPLATE_CONTEXT_PROCESSOR

October 27th, 2013, Posted by: agon   

看到the django book第九章里关于template_context_processor,有些内容太老,也没有给出自定义template_context_processor实例,所以写了一个总结。

创建一个context processor函数

新建一个文件命名为context_processors.py,把它和项目的settings文件放在一个文件夹内,添加一个返回字典的函数,其代码如下:

#context_processors.py
def foos(request): 
    context = {'FOO': 'context processor test:foos'}
    return context

修改 settings 文件

打开项目的settings.py文件,添加如下代码:

#settings.py【1】
#这里用import,目的是为了不修改global_settings文件,只修改本地配置文件
from django.conf import global_settings

#添加自定义的处理函数
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( "mysite.context_processors.foos", )

说一下上面的代码,+后面的元组可以添加多个自定义的处理函数,如果只有一个别忘了后面的逗号。

在views中调用

views中函数的return有两种写法,一种是render,一种是render_to_response,这里推荐render而不是render_to_response【2】,因为render_to_response必须要使用这个参数context_instance=RequestContext(request)才能使用默认的template_context_processors。

模板中添加自定义的变量

在要测试的模板里添加{{FOO}},访问的时候就会变成我们赋予其的值了。

由于在TEMPLATE_CONTEXT_PROCESSORS添加的函数在settings里,即使你不调用它,所有的views都自动调用它,可能会带来性能影响,请酌情使用【3】

windows64位下python3配合apache与wsgi部署django项目

October 26th, 2013, Posted by: agon   

初学django,想在windows下,用apache和mod_wsgi部署一个简单的django学习环境,没想到由于操作系统用的是win8 64位和python3,安装的并不顺利,本文即对安装过程的总结。

搭建环境及准备

  • 操作系统;win8.1 64位
  • python版本:pyton3.3.2 64位
  • django版本:django-1.5.4
  • 准备一个可以runserver下正常用的django project

注意上面python安装的版本是64位的。

安装apache

这里需要安装apche64位版本,否则wsgi会不认,无法加载,造成apche无法启动。可以直接到awamp下载一个套件,或者到aapachelounge下载已经编译好的单独的64位apache,本文的apache版本是2.4.4。wamp正常的安装就可以了,apachelounge的应该是绿色版的。

安装mod_wsgi

官方最新的版本是3.4,只有python2.6和2.7的,没有python3的。我们不用自己编译(在windows下几乎没有编译成功过),有现成的,到http://www.lfd.uci.edu/下载需要的版本(这里有很多windows下的编译好的扩展),根据本文环境选择mod_wsgi-3.4.ap24.win32-py3.3.zip,之后搭建成功后,访问网页,得到的http头里的server显示是mod_wsgi/3.5-BRANC。

解压压缩包,把mod_wsgi.so文件拷进apache安装路径的modules文件夹下,打开httpd.conf,添加一行LoadModule wsgi_module modules/mod_wsgi.so。cmd命令行窗口,执行apache的bin目录下的httpd,如果没有任何报错,应该就正常加载了。

部署django项目

假设你用django-admin.py startproject mysite,创建一个mysite的项目,它的目录结构如下:

项目目录结构

假设你的项目在D盘根目录,我们就此来配置项目。

添加程序入口文件

在mysite项目根目录,新建apche目录,这个目录在manage.py那个文件所在的目录,在其下面新建django.wsgi,将来WSGI连接它来代替默认的mange.py,作为网站的入口配置。在其内添加如下代码:

import os
import sys

#添加setting文件地址
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
#添加项目路径到sys.path
sys.path.append('D:/mysite')
 
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

上面的代码只修改为你项目的地址和对应名称,后面conf配置的时候用到这个文件的地址。

配置虚拟主机

因为可能同时要运行多个项目,而且还有其他语言的项目,所以用vhost来配置是最方便的。到apache安装目录的conf\extra里找到httpd-vhosts.conf文件,这个文件是虚拟主机的配置文件【1】,编辑打开,贴入如下代码:

#如果是80端口这句不用写,主配置文件httpd.conf已经有了
#Listen 80 
#这句貌似也不用,2.4的不需要这句
#NameVirtualHost *:80 

#配置端口号,*可以换成主机ip,如果ip不固定,就有*就好了,很方便
<VirtualHost *:80> 
	#配置访问的域名
	ServerName example.com
	#配置主目录权限
	<Directory />
	    Options FollowSymLinks 
	    AllowOverride 
	    Order allow,deny 
	    Allow from all 
	</Directory>

	#配置项目配置文件目录权限,禁止访问
	<Directory "D:/mysite/mysite/"> 
	    Order Deny,Allow 
	    Deny from all 
	</Directory> 

	#关键一句配置项目入口点
	WSGIScriptAlias / "D:/mysite/apache/django.wsgi"

	#配置管理员静态文件目录,及其权限
	Alias /static/admin D:/Python33/Lib/site-packages/django-1.5.4-py3.3.egg/django/contrib/admin/static/admin
	<Directory "D:/Python33/Lib/site-packages/django-1.5.4-py3.3.egg/django/contrib/admin/static/admin/"> 
	    Order allow,deny 
	    Allow from all 
	</Directory> 

	#配置静态文件目录,及其权限
	Alias /static D:/mysite/static/
	<Directory "D:/mysite/static/"> 
	    Order allow,deny 
	    Allow from all 
	</Directory> 

</VirtualHost>

下面说一说上面代码里应该注意的地方:

  • 首先,项目结构如前面图片,假设保存在D盘,前面几句是主机地址、域名以及涉及目录权限的相关设置,到达WSGIScriptAlias这里,就填上刚才添加的django.wsgi的地址,这里是配置成功与否的关键。
  • 凡是不想让wsgi处理,按实际文件夹结构访问的,都可以用Alias来添加,这样访问的时候就不会去找urls里配view了。添加的时候注意Alias第一个目录后面不要用/结尾。 【2】 本例以static目录为静态文件夹
  • 本例使用static为静态文件目录,因为django1.5的admin的静态文件地址为域名/stacic/admin/*。另外注意的是django1.5不在使用media文件存放静态文件,改为contrib/admin/static/admin了。如果你想把其他静态文件也放在static下面,记住Alias /static一定要在Alias /static/admin后面,要不然由于优先级造成短路,登陆admin的时候,admin的静态文件永远也不会加载的。
  • 最后到编辑httpd.conf文件,取消Include conf/extra/httpd-vhosts.conf的注释,并保存。

至此,部署完成,当然这只是windows下用python3学django的一个学习环境,仅供学习用。另外,wsgi有两种运行模式:一种是daemon mode,一种是embedded mode。在daemon mode下,每次修改不用重启apche,windows下不支持,修改完代码只能重启apche,还有就是不要忘了吧settings.py里的ALLOWED_HOSTS填上你的域名。

python3.3下实现django连接mysql

October 20th, 2013, Posted by: agon   

想了解一下django,发现虽然django最新版已经支持python3,但是dajango用来连接mysql的mysqldb,却支持python2.7。虽然有很多支持python3的mysql连接器,但是dajango不支持。好在9月份,mysql官方连接器的一个beta版,已经有支持dajango的模块了,使用它就可以在python3和django1.5环境下使用mysql了。

搭建环境

  • 操作系统;win8
  • python版本:pyton3.3
  • django版本:django-1.5.4
  • mysql版本: 5.6.11 MySQL Community Server (GPL)

请确保以上涉及到的软件都正常工作。

安装mysql连接器(Connector/Python)

下载安装文件:

官方下载 最新版的稳定版连接器和alpha版,两个都下载,或者直接点以下两个链接:
alpha版 稳定版

我用的是windows,linux环境的也有提供,请点上面官方页面,注意那个页面默认看的是Generally Available (GA) Releases,点它旁边的Development Releases才能看到alpha版下载信息。

安装下载文件:

之所以下两个版本,请看后面的常见问题。

  1. 安装alpha版,然后到\Lib\site-packages\mysql\connector安装目录下找到version.py,复制一份。
  2. 安装稳定版,同样在这个目录下删掉version.py,把复制的那一份改成这个名字。
  3. 编辑Lib\site-packages\mysql\connector\django目录下base.py,在第278行找到return cursor.statement.decode('utf-8')修改为return cursor

设置与测试:

在你django的project里打开seetyong.py,按照下面设置:【1】

DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django', # 这里是关键填我们装的backend.
        'NAME': '填你的数据库名字',                      
        'USER': '用户名',
        'PASSWORD': '密码',
        'HOST': '', 
        'PORT': '端口号', 
    }
}

上面填好之后,在project的manage.py目录,打开命令行工具,运行python manage.py shell命令,如果进入shell环境,参考下面的命令来测试:

>>> from django.db import connection
>>> cursor = connection.cursor()

上面两行如果没错,说明数据库设置正常,连接器配置成功

>>> cursor.execute("select * from books_publisher")
>>> cursor.fetchone()

把上面的books_publisher换成你数据库里有数据的表名,如果fetchone()执行完,有数据返回说明连接器基本没什么问题,可以用于一般的学习了

安装期间及测试出现的问题及解决

  • 只安装alpha版,在数据库关闭连接时老是蹦出异常:

    刚开始时只安装了alpha版,发现在执行完一般的mysql脚本好老是蹦出异常,type错误好像是,即连接器close()关闭连接后,connection.py在执行__del__报错。而稳定版没问题,由于稳定版没有django模块,所以先装alpha版后增加django模块,再装稳定版,覆盖alpha的其他文件成稳定版的。

  • 在执行python manage.py shell时找不到version:

    这就是前面为什么要复制一分alpha版的version.py文件,因为稳定版的版本号会提示错误,里面知识版本号数字,替换不影响使用。

  • 在执行cursor.execute来selct数据库时提示编码错误:

    在从数据库里取数据时会提示以下错误:
    return cursor.statement.decode('utf-8')
    AttributeError: 'str' object has no attribute 'decode'

    修改方法如前文安装所述sup【2】

经过一番折腾,做了一个小实例,没发现什么问题,在学习环境中使用很方便,其实用postgresql可能更方便了。眼下随着支持python3的插件越来越多,觉得用python3学django正是时候。

python list 多个关键字排序

October 17th, 2013, Posted by: agon   

问题:

python对list排序可以用L.sort(key = )设置一个参照给key参数,以其为标准进行排序。如果对一个多维序列排序,势必未遇到排序的关键字的值有相等的情况下,想以以第二关键字进行排序,如[(1,3,5),(1,4,3)],假如以[0]为关键字值都为一,当[0]都是1的时候,以[2]为关键字,即得出[(1,4,3),(1,3,5)]。

解决:

l=[(1,4,3),(1,3,5),(1,2,2)]
l.sort(key = lambda x: (x[0],x[2]))
print(l)
#output:
#[(1, 2, 2), (1, 4, 3), (1, 3, 5)]

讨论:

以前以为用cmp参数,python3已经禁用cmp,其实给key一个tuple【1】就可以了很简单就可解决,这样sort就以(第一关键字,第二关键字)的顺序进行排序了,如果想加入更多关键字,那就只管往tuple里加就行了。

使用eric5集成环境写qt gui程序

February 17th, 2013, Posted by: agon   

Python的qyqt结合Qt designer,自定义slot的时候总是要手动连接和自定义函数,而且要手动转ui文件,很麻烦,幸好有一款叫eric的ide,整合了qt designer,可以使python像在qt creater下一样使用Qt designer。下面讲解一个利用此集成环境做的一个最简单gui程序。

本文假设你曾经在非集成环境下用pyuic4生成过python脚本,没有也没关系,照着做就行了,推荐阅读一下Introduction to Python Programming and Developing GUI Applications with PyQT里的第七章PyQT(下载)。

本文十分基础,而且有点罗嗦,请高手飘过,新手选读。

准备工作:

安装最新版的python

本文为3.3版

安装最新版的pyqt

本文版本为4.9.6-1,安装位置在python目录

安装最新版qt

本文为版本5.01,安装文件800多MB,安装需要4G左右安装空间,请留足空间。安装路径自定义就可以了,其余默认

安装eric5

a.下载页面点击Download eric5 到下载页面,找到最新版本,本文使用的是5.3,如果不想使用英文版,可以同时下载中文包
b.解压文件,到解压目录,运行install.py,完成安装
c.命令行下输入eric5或者在安装目录下双击eric5.pyw(可能会有cmd窗口,右键属性,默认打开方式选择python安装目录下的pythonw.exe),就能打开eric5

配置

初次打开,提示初始化设置,本文只涉及基本的简单设置,具体个性化设置,以后更改可以在Settings > Preferences下更改,请参考官方文档
1.点击Eidtor>APIs,勾选Compile APIs automatically,在Language下拉菜单下选择Python3,点击Add from installed APIs,选择你需要的APIs。最后点击Compile APIs,等待几分钟,编译完后点Apply。


图2.1
2.点击Eidtor>Autocompletion,勾选所有选项,点击Eidtor>AutocompletionQ>Scintilla,选from Document and API files,Apply。
3.点击确定

第一个程序

创建新project

打开eric5,点击Project > new,跳出一个对话框, 在这儿你可以设置一些project属性,这里面主要涉及的是项目名称(这里命名为Welcome)和目录位置(自定义)。

图3.1
点击确定,然后蹦出一个对话框,是否添加已经存在的python,这里选择否。

创建form

a.在左侧的project viewe里,点击左上角的form选项卡,在空白区域右键,选择New form。

图3.2
b.我们使用QtDesigner设计程序界面,在跳出的对话框里选择Dialog,然后点击OK。然后在保存对话框里选择新建文件夹,命名为ui(另一种创建文件夹的方法是在source选项里,右键 > new package)。进入ui文件夹,保存为Welcome.ui。此时form项里已经出现我们刚才创建的Welcome.ui文件。

图3.3
c.在创建ui文件的同时,会自动打开QtDesigner,你也可以在form选项里双击Welcome.ui来打开QtDesigner。按照下图创建程序界面

图3.4

创建预定义的连接

Signals/Slots。点击QtDesigner工具栏上的Edit Signals/Slots(F4),进入编辑模式,鼠标放到clear按钮上方,按钮变红,按住鼠标向上拖动到文本框,松开鼠标,跳出连接设置对话框。按下图选择对应的选项,确定。

图3.5
便在按钮和文本框之间创建连接,当按钮被点击发出clicked()信号,文本框接收信号,调动clear()槽(slot)方法,清空文本框里的文字。你可以按下Ctrl+R组合键,来调出一个实例,在文本框里输入文字,然后点击clear。
点击保存,关闭QtDesigner。

编译与运行程序

a.回到eric5的form选项卡里,右键Welcome.ui,点击Compile form。这将.ui文件(实际为xml)当做输入文件生成对应的python代码文件(Ui_welcome.py)。在Project viewer里的sources选项卡里可以看到,这个文件里包含一个Ui_Dialog类,我们创建的界面元素及信号与槽的连接,都通过这个类创建。
b.我们还要新建一个文件来调用UI_Dialog执行程序。我们在sources选项卡里的根目录下,右键,选择add source files,在source Files(在打开对话框里右键新建文件,显示所有后缀,重命名)里新建一个callWelcome.py勾选Is sourcecode files。

图3.6
c.在callWelcome.py里添加以下代码(本文不解释代码含义,推荐阅读本节开头介绍的图书章节):

import sys

from ui.Ui_welcome import * #调用界面python代码

class MyForm(QtGui.QDialog):

    def __init__(self, parent=None):

        QtGui.QWidget.__init__(self, parent)

        self.ui = Ui_Dialog()

        self.ui.setupUi(self)

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)

    myapp = MyForm()

    myapp.show()

    sys.exit(app.exec_())

d.保存后,点击菜单Project > Properties,在main script 选项里选择callWelcome.py为main script,确定。
e.在菜单里选择Start > Run project。蹦出一个对话框,按下图修改

图3.7
f.点击确定,蹦出程序界面。我们的第一个程序完成。

修改第一个程序

第一个程序完成,显然它和我们的程序名weilcome不符,我们要做的程序是点击button会显示hello+文本框里的名字。但是预定义里没有这样的slot(槽)方法,这就需要我们自定义一个slot。一般的方法是在callWelcome.py里的MyForm类里自定义一个方法,再用QtCore.QObject.connect来连接。记住不能写在通过ui文件自动生成的py文件里,如果那样做的话,下次修改界面重新生成时,会覆盖之前自己写的方法。用这个方法有一点烦人,每次自定义slot方法,都要手动定义方法,写连接命令,而且库名字很容易打错,用eric5的目的就是省去这些步骤,直接写方法,把精力用在自定义方法的内容上。

准备工作

保存project,然后关闭。因为没用版本控制,用原始的方法,把welcome的project文件夹复制出来一份,另存为,重名为welcome2。打开eric5,在菜单栏选择project > open,打开welcome2文件夹里的Welcome.e4p。点击菜单Project > Properties,在project 选项里把路径里的welcome改为welcome2。
或者直接忽略上面一段话。

修改界面

a.在左侧的project viewe里,点击左上角的form选项卡,双击welcome.ui,打开QtDesigner。
b.按照下图添加pushButton和label:

图4.1
对象的文字删掉后在界面上就看不到了,它还存在着,在对象查看器里依然可以看到。
c.回到eric5的form选项卡里,右键Welcome.ui,点击Compile form。
每次修改完界面,都要重新compile。

创建自定义slot

a.下面就到本文重点了,为了让我们自定义的方法不被ui-complier自动生成的类覆盖,我们要创建一个文件,里面包含一个自定义的类,并且这个类继承ui文件自动生成的类。Eric5使这一切都很方便:
右键welcome.ui,选择Generate dialog code。此时弹出一个对话框,如下图:


图4.2
点击new,跳出一个对话框,如下图

图4.3
图里的文本是自动生成的,因为我们创建的界面是Dialog,所以类名是Dialog,文件名welcome.py,根据ui名生成,这里都可以自定义,我们用默认的。点击确定,回到刚才的对话框。
在filter with下方,我们会看到所有在QtDesigner里创建的对象,以及它们预定义的方法。我们只需要hello这个button click事件,来触发自定义的slot。按照下图选择,然后确定。


图4.4
3.在source选项卡里我们就能看到eric5生成的welcome.py。双击在编辑器里打开,找到如下代码:
<

    @pyqtSlot()

    def on_buttonHello_clicked(self):

        """

        Slot documentation goes here.

        """

        # TODO: not implemented yet

        raise NotImplementedError

把raise NotImplementedError,修改为自定义的代码,修改代码如下:

    @pyqtSlot()

    def on_buttonHello_clicked(self):

        """

        Slot documentation goes here.

        """

        #当点击hello button的时候,把labelMessage的text改为lineUserNam里的文字

        self.labelMessage.setText("Hello " + self.lineUserNam.text())

修改main scrpt运行程序

a.因为我们不从生成的UI_welcome.py生成程序界面,而是通过welcome.py里继承的Dialog类,所以要改一下callWelcome.py这个文件,更改如下:

import sys

from PyQt4.QtGui import QApplication #添加

from ui.welcome import * #这里有修改

 

if __name__ == "__main__":

    app = QApplication(sys.argv) #修改

    myapp = Dialog()

    myapp.show()

sys.exit(app.exec_())

b.在菜单里选择Start > Run project。蹦出对话框,确保directory位置和在当前project存放位置一样。

在文本框内输入world,点击hello,显示hello world。

完毕,容易错地地方:

  1. 自定义方法里的对象名打错,和ui里的不一样。
  2. 每次修改完ui,都要点compile
  3. 运行时确定main script和 project目录正确

好长时间没写博客,用word写完,去掉垃圾代码,粘过来还是乱七八糟,word文章下载地址

文章参考:

网址:

官方教程:http://eric-ide.python-projects.org/eric-tutorials.html

书:

Introduction to Python Programming and Developing GUI Applications with PyQT里的第七章

代码下载:
http://ubuntuone.com/2PV5w09KstmM3zzNYCpYyE

Page 1 of 11