成人动漫av,欧美国产一区二区三区激情无套,外国成人激情视频http://www.aygfsteel.com/sealyu/category/34557.html--- The devil's in the Detailszh-cnTue, 18 May 2010 10:27:00 GMTTue, 18 May 2010 10:27:00 GMT60MySQLdb User's Guidehttp://www.aygfsteel.com/sealyu/archive/2010/05/17/321217.htmlsealsealMon, 17 May 2010 15:56:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/05/17/321217.htmlhttp://www.aygfsteel.com/sealyu/comments/321217.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/05/17/321217.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/321217.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/321217.html

Contents

Introduction

MySQLdb is an thread-compatible interface to the popular MySQL database server that provides the Python database API.

Installation

The README file has complete installation instructions.

_mysql

If you want to write applications which are portable across databases, use MySQLdb, and avoid using this module directly. _mysql provides an interface which mostly implements the MySQL C API. For more information, see the MySQL documentation. The documentation for this module is intentionally weak because you probably should use the higher-level MySQLdb module. If you really need it, use the standard MySQL docs and transliterate as necessary.

MySQL C API translation

The MySQL C API has been wrapped in an object-oriented way. The only MySQL data structures which are implemented are the MYSQL (database connection handle) and MYSQL_RES (result handle) types. In general, any function which takes MYSQL *mysql as an argument is now a method of the connection object, and any function which takes MYSQL_RES *result as an argument is a method of the result object. Functions requiring none of the MySQL data structures are implemented as functions in the module. Functions requiring one of the other MySQL data structures are generally not implemented. Deprecated functions are not implemented. In all cases, the mysql_ prefix is dropped from the name. Most of the conn methods listed are also available as MySQLdb Connection object methods. Their use is non-portable.

MySQL C API function mapping

C API _mysql
mysql_affected_rows() conn.affected_rows()
mysql_autocommit() conn.autocommit()
mysql_character_set_name() conn.character_set_name()
mysql_close() conn.close()
mysql_commit() conn.commit()
mysql_connect() _mysql.connect()
mysql_data_seek() result.data_seek()
mysql_debug() _mysql.debug()
mysql_dump_debug_info conn.dump_debug_info()
mysql_escape_string() _mysql.escape_string()
mysql_fetch_row() result.fetch_row()
mysql_get_character_set_info() conn.get_character_set_info()
mysql_get_client_info() _mysql.get_client_info()
mysql_get_host_info() conn.get_host_info()
mysql_get_proto_info() conn.get_proto_info()
mysql_get_server_info() conn.get_server_info()
mysql_info() conn.info()
mysql_insert_id() conn.insert_id()
mysql_num_fields() result.num_fields()
mysql_num_rows() result.num_rows()
mysql_options() various options to _mysql.connect()
mysql_ping() conn.ping()
mysql_query() conn.query()
mysql_real_connect() _mysql.connect()
mysql_real_query() conn.query()
mysql_real_escape_string() conn.escape_string()
mysql_rollback() conn.rollback()
mysql_row_seek() result.row_seek()
mysql_row_tell() result.row_tell()
mysql_select_db() conn.select_db()
mysql_set_character_set() conn.set_character_set()
mysql_ssl_set() ssl option to _mysql.connect()
mysql_stat() conn.stat()
mysql_store_result() conn.store_result()
mysql_thread_id() conn.thread_id()
mysql_thread_safe_client() conn.thread_safe_client()
mysql_use_result() conn.use_result()
mysql_warning_count() conn.warning_count()
CLIENT_* MySQLdb.constants.CLIENT.*
CR_* MySQLdb.constants.CR.*
ER_* MySQLdb.constants.ER.*
FIELD_TYPE_* MySQLdb.constants.FIELD_TYPE.*
FLAG_* MySQLdb.constants.FLAG.*

Some _mysql examples

Okay, so you want to use _mysql anyway. Here are some examples.

The simplest possible database connection is:

import _mysql
db=_mysql.connect()

This creates a connection to the MySQL server running on the local machine using the standard UNIX socket (or named pipe on Windows), your login name (from the USER environment variable), no password, and does not USE a database. Chances are you need to supply more information.:

db=_mysql.connect("localhost","joebob","moonpie","thangs")

This creates a connection to the MySQL server running on the local machine via a UNIX socket (or named pipe), the user name "joebob", the password "moonpie", and selects the initial database "thangs".

We haven't even begun to touch upon all the parameters connect() can take. For this reason, I prefer to use keyword parameters:

db=_mysql.connect(host="localhost",user="joebob",
passwd="moonpie",db="thangs")

This does exactly what the last example did, but is arguably easier to read. But since the default host is "localhost", and if your login name really was "joebob", you could shorten it to this:

db=_mysql.connect(passwd="moonpie",db="thangs")

UNIX sockets and named pipes don't work over a network, so if you specify a host other than localhost, TCP will be used, and you can specify an odd port if you need to (the default port is 3306):

db=_mysql.connect(host="outhouse",port=3307,passwd="moonpie",db="thangs")

If you really had to, you could connect to the local host with TCP by specifying the full host name, or 127.0.0.1.

Generally speaking, putting passwords in your code is not such a good idea:

db=_mysql.connect(host="outhouse",db="thangs",read_default_file="~/.my.cnf")

This does what the previous example does, but gets the username and password and other parameters from ~/.my.cnf (UNIX-like systems). Read about option files for more details.

So now you have an open connection as db and want to do a query. Well, there are no cursors in MySQL, and no parameter substitution, so you have to pass a complete query string to db.query():

db.query("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < 5""")

There's no return value from this, but exceptions can be raised. The exceptions are defined in a separate module, _mysql_exceptions, but _mysql exports them. Read DB API specification PEP-249 to find out what they are, or you can use the catch-all MySQLError.

At this point your query has been executed and you need to get the results. You have two options:

r=db.store_result()
# ...or...
r=db.use_result()

Both methods return a result object. What's the difference? store_result() returns the entire result set to the client immediately. If your result set is really large, this could be a problem. One way around this is to add a LIMIT clause to your query, to limit the number of rows returned. The other is to use use_result(), which keeps the result set in the server and sends it row-by-row when you fetch. This does, however, tie up server resources, and it ties up the connection: You cannot do any more queries until you have fetched all the rows. Generally I recommend using store_result() unless your result set is really huge and you can't use LIMIT for some reason.

Now, for actually getting real results:

>>> r.fetch_row()
(('3','2','0'),)

This might look a little odd. The first thing you should know is, fetch_row() takes some additional parameters. The first one is, how many rows (maxrows) should be returned. By default, it returns one row. It may return fewer rows than you asked for, but never more. If you set maxrows=0, it returns all rows of the result set. If you ever get an empty tuple back, you ran out of rows.

The second parameter (how) tells it how the row should be represented. By default, it is zero which means, return as a tuple. how=1 means, return it as a dictionary, where the keys are the column names, or table.column if there are two columns with the same name (say, from a join). how=2 means the same as how=1 except that the keys are always table.column; this is for compatibility with the old Mysqldb module.

OK, so why did we get a 1-tuple with a tuple inside? Because we implicitly asked for one row, since we didn't specify maxrows.

The other oddity is: Assuming these are numeric columns, why are they returned as strings? Because MySQL returns all data as strings and expects you to convert it yourself. This would be a real pain in the ass, but in fact, _mysql can do this for you. (And MySQLdb does do this for you.) To have automatic type conversion done, you need to create a type converter dictionary, and pass this to connect() as the conv keyword parameter.

The keys of conv should be MySQL column types, which in the C API are FIELD_TYPE_*. You can get these values like this:

from MySQLdb.constants import FIELD_TYPE

By default, any column type that can't be found in conv is returned as a string, which works for a lot of stuff. For our purposes, we probably want this:

my_conv = { FIELD_TYPE.LONG: int }

This means, if it's a FIELD_TYPE_LONG, call the builtin int() function on it. Note that FIELD_TYPE_LONG is an INTEGER column, which corresponds to a C long, which is also the type used for a normal Python integer. But beware: If it's really an UNSIGNED INTEGER column, this could cause overflows. For this reason, MySQLdb actually uses long() to do the conversion. But we'll ignore this potential problem for now.

Then if you use db=_mysql.connect(conv=my_conv...), the results will come back ((3, 2, 0),), which is what you would expect.

MySQLdb

MySQLdb is a thin Python wrapper around _mysql which makes it compatible with the Python DB API interface (version 2). In reality, a fair amount of the code which implements the API is in _mysql for the sake of efficiency.

The DB API specification PEP-249 should be your primary guide for using this module. Only deviations from the spec and other database-dependent things will be documented here.

Functions and attributes

Only a few top-level functions and attributes are defined within MySQLdb.

connect(parameters...)

Constructor for creating a connection to the database. Returns a Connection Object. Parameters are the same as for the MySQL C API. In addition, there are a few additional keywords that correspond to what you would pass mysql_options() before connecting. Note that some parameters must be specified as keyword arguments! The default value for each parameter is NULL or zero, as appropriate. Consult the MySQL documentation for more details. The important parameters are:

host
name of host to connect to. Default: use the local host via a UNIX socket (where applicable)
user
user to authenticate as. Default: current effective user.
passwd
password to authenticate with. Default: no password.
db
database to use. Default: no default database.
port
TCP port of MySQL server. Default: standard port (3306).
unix_socket
location of UNIX socket. Default: use default location or TCP for remote hosts.
conv
type conversion dictionary. Default: a copy of MySQLdb.converters.conversions
compress
Enable protocol compression. Default: no compression.
connect_timeout
Abort if connect is not completed within given number of seconds. Default: no timeout (?)
named_pipe
Use a named pipe (Windows). Default: don't.
init_command
Initial command to issue to server upon connection. Default: Nothing.
read_default_file
MySQL configuration file to read; see the MySQL documentation for mysql_options().
read_default_group
Default group to read; see the MySQL documentation for mysql_options().
cursorclass
cursor class that cursor() uses, unless overridden. Default: MySQLdb.cursors.Cursor. This must be a keyword parameter.
use_unicode

If True, CHAR and VARCHAR and TEXT columns are returned as Unicode strings, using the configured character set. It is best to set the default encoding in the server configuration, or client configuration (read with read_default_file). If you change the character set after connecting (MySQL-4.1 and later), you'll need to put the correct character set name in connection.charset.

If False, text-like columns are returned as normal strings, but you can always write Unicode strings.

This must be a keyword parameter.

charset

If present, the connection character set will be changed to this character set, if they are not equal. Support for changing the character set requires MySQL-4.1 and later server; if the server is too old, UnsupportedError will be raised. This option implies use_unicode=True, but you can override this with use_unicode=False, though you probably shouldn't.

If not present, the default character set is used.

This must be a keyword parameter.

sql_mode

If present, the session SQL mode will be set to the given string. For more information on sql_mode, see the MySQL documentation. Only available for 4.1 and newer servers.

If not present, the session SQL mode will be unchanged.

This must be a keyword parameter.

ssl
This parameter takes a dictionary or mapping, where the keys are parameter names used by the mysql_ssl_set MySQL C API call. If this is set, it initiates an SSL connection to the server; if there is no SSL support in the client, an exception is raised. This must be a keyword parameter.
apilevel
String constant stating the supported DB API level. '2.0'
threadsafety

Integer constant stating the level of thread safety the interface supports. This is set to 1, which means: Threads may share the module.

The MySQL protocol can not handle multiple threads using the same connection at once. Some earlier versions of MySQLdb utilized locking to achieve a threadsafety of 2. While this is not terribly hard to accomplish using the standard Cursor class (which uses mysql_store_result()), it is complicated by SSCursor (which uses mysql_use_result(); with the latter you must ensure all the rows have been read before another query can be executed. It is further complicated by the addition of transactions, since transactions start when a cursor execute a query, but end when COMMIT or ROLLBACK is executed by the Connection object. Two threads simply cannot share a connection while a transaction is in progress, in addition to not being able to share it during query execution. This excessively complicated the code to the point where it just isn't worth it.

The general upshot of this is: Don't share connections between threads. It's really not worth your effort or mine, and in the end, will probably hurt performance, since the MySQL server runs a separate thread for each connection. You can certainly do things like cache connections in a pool, and give those connections to one thread at a time. If you let two threads use a connection simultaneously, the MySQL client library will probably upchuck and die. You have been warned.

For threaded applications, try using a connection pool. This can be done using the Pool module.

charset
The character set used by the connection. In MySQL-4.1 and newer, it is possible (but not recommended) to change the connection's character set with an SQL statement. If you do this, you'll also need to change this attribute. Otherwise, you'll get encoding errors.
paramstyle

String constant stating the type of parameter marker formatting expected by the interface. Set to 'format' = ANSI C printf format codes, e.g. '...WHERE name=%s'. If a mapping object is used for conn.execute(), then the interface actually uses 'pyformat' = Python extended format codes, e.g. '...WHERE name=%(name)s'. However, the API does not presently allow the specification of more than one style in paramstyle.

Note that any literal percent signs in the query string passed to execute() must be escaped, i.e. %%.

Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.

conv

A dictionary or mapping which controls how types are converted from MySQL to Python and vice versa.

If the key is a MySQL type (from FIELD_TYPE.*), then the value can be either:

  • a callable object which takes a string argument (the MySQL value),' returning a Python value
  • a sequence of 2-tuples, where the first value is a combination of flags from MySQLdb.constants.FLAG, and the second value is a function as above. The sequence is tested until the flags on the field match those of the first value. If both values are None, then the default conversion is done. Presently this is only used to distinquish TEXT and BLOB columns.

If the key is a Python type or class, then the value is a callable Python object (usually a function) taking two arguments (value to convert, and the conversion dictionary) which converts values of this type to a SQL literal string value.

This is initialized with reasonable defaults for most types. When creating a Connection object, you can pass your own type converter dictionary as a keyword parameter. Otherwise, it uses a copy of MySQLdb.converters.conversions. Several non-standard types are returned as strings, which is how MySQL returns all columns. For more details, see the built-in module documentation.

Connection Objects

Connection objects are returned by the connect() function.

commit()
If the database and the tables support transactions, this commits the current transaction; otherwise this method successfully does nothing.
rollback()
If the database and tables support transactions, this rolls back (cancels) the current transaction; otherwise a NotSupportedError is raised.
cursor([cursorclass])
MySQL does not support cursors; however, cursors are easily emulated. You can supply an alternative cursor class as an optional parameter. If this is not present, it defaults to the value given when creating the connection object, or the standard Cursor class. Also see the additional supplied cursor classes in the usage section.

There are many more methods defined on the connection object which are MySQL-specific. For more information on them, consult the internal documentation using pydoc.

Cursor Objects

callproc(procname, args)

Calls stored procedure procname with the sequence of arguments in args. Returns the original arguments. Stored procedure support only works with MySQL-5.0 and newer.

Compatibility note: PEP-249 specifies that if there are OUT or INOUT parameters, the modified values are to be returned. This is not consistently possible with MySQL. Stored procedure arguments must be passed as server variables, and can only be returned with a SELECT statement. Since a stored procedure may return zero or more result sets, it is impossible for MySQLdb to determine if there are result sets to fetch before the modified parmeters are accessible.

The parameters are stored in the server as @_*procname*_*n*, where n is the position of the parameter. I.e., if you cursor.callproc('foo', (a, b, c)), the parameters will be accessible by a SELECT statement as @_foo_0, @_foo_1, and @_foo_2.

Compatibility note: It appears that the mere act of executing the CALL statement produces an empty result set, which appears after any result sets which might be generated by the stored procedure. Thus, you will always need to use nextset() to advance result sets.

close()
Closes the cursor. Future operations raise ProgrammingError. If you are using server-side cursors, it is very important to close the cursor when you are done with it and before creating a new one.
info()
Returns some information about the last query. Normally you don't need to check this. If there are any MySQL warnings, it will cause a Warning to be issued through the Python warning module. By default, Warning causes a message to appear on the console. However, it is possible to filter these out or cause Warning to be raised as exception. See the MySQL docs for mysql_info(), and the Python warning module. (Non-standard)
setinputsizes()
Does nothing, successfully.
setoutputsizes()
Does nothing, successfully.
nextset()

Advances the cursor to the next result set, discarding the remaining rows in the current result set. If there are no additional result sets, it returns None; otherwise it returns a true value.

Note that MySQL doesn't support multiple result sets until 4.1.

Some examples

The connect() method works nearly the same as with _mysql:

import MySQLdb
db=MySQLdb.connect(passwd="moonpie",db="thangs")

To perform a query, you first need a cursor, and then you can execute queries on it:

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))

In this example, max_price=5 Why, then, use %s in the string? Because MySQLdb will convert it to a SQL literal value, which is the string '5'. When it's finished, the query will actually say, "...WHERE price < 5".

Why the tuple? Because the DB API requires you to pass in any parameters as a sequence. Due to the design of the parser, (max_price) is interpreted as using algebraic grouping and simply as max_price and not a tuple. Adding a comma, i.e. (max_price,) forces it to make a tuple.

And now, the results:

>>> c.fetchone()
(3L, 2L, 0L)

Quite unlike the _mysql example, this returns a single tuple, which is the row, and the values are properly converted by default... except... What's with the L's?

As mentioned earlier, while MySQL's INTEGER column translates perfectly into a Python integer, UNSIGNED INTEGER could overflow, so these values are converted to Python long integers instead.

If you wanted more rows, you could use c.fetchmany(n) or c.fetchall(). These do exactly what you think they do. On c.fetchmany(n), the n is optional and defaults to c.arraysize, which is normally 1. Both of these methods return a sequence of rows, or an empty sequence if there are no more rows. If you use a weird cursor class, the rows themselves might not be tuples.

Note that in contrast to the above, c.fetchone() returns None when there are no more rows to fetch.

The only other method you are very likely to use is when you have to do a multi-row insert:

c.executemany(
"""INSERT INTO breakfast (name, spam, eggs, sausage, price)
VALUES (%s, %s, %s, %s, %s)""",
[
("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
] )

Here we are inserting three rows of five values. Notice that there is a mix of types (strings, ints, floats) though we still only use %s. And also note that we only included format strings for one row. MySQLdb picks those out and duplicates them for each row.

Using and extending

In general, it is probably wise to not directly interact with the DB API except for small applicatons. Databases, even SQL databases, vary widely in capabilities and may have non-standard features. The DB API does a good job of providing a reasonably portable interface but some methods are non-portable. Specifically, the parameters accepted by connect() are completely implementation-dependent.

If you believe your application may need to run on several different databases, the author recommends the following approach, based on personal experience: Write a simplified API for your application which implements the specific queries and operations your application needs to perform. Implement this API as a base class which should be have few database dependencies, and then derive a subclass from this which implements the necessary dependencies. In this way, porting your application to a new database should be a relatively simple matter of creating a new subclass, assuming the new database is reasonably standard.

Because MySQLdb's Connection and Cursor objects are written in Python, you can easily derive your own subclasses. There are several Cursor classes in MySQLdb.cursors:

BaseCursor
The base class for Cursor objects. This does not raise Warnings.
CursorStoreResultMixIn
Causes the Cursor to use the mysql_store_result() function to get the query result. The entire result set is stored on the client side.
CursorUseResultMixIn
Causes the cursor to use the mysql_use_result() function to get the query result. The result set is stored on the server side and is transferred row by row using fetch operations.
CursorTupleRowsMixIn
Causes the cursor to return rows as a tuple of the column values.

CursorDictRowsMixIn

Causes the cursor to return rows as a dictionary, where the keys are column names and the values are column values. Note that if the column names are not unique, i.e., you are selecting from two tables that share column names, some of them will be rewritten as table.column. This can be avoided by using the SQL AS keyword. (This is yet-another reason not to use * in SQL queries, particularly where JOIN is involved.)
Cursor
The default cursor class. This class is composed of CursorWarningMixIn, CursorStoreResultMixIn, CursorTupleRowsMixIn, and BaseCursor, i.e. it raises Warning, uses mysql_store_result(), and returns rows as tuples.
DictCursor
Like Cursor except it returns rows as dictionaries.
SSCursor
A "server-side" cursor. Like Cursor but uses CursorUseResultMixIn. Use only if you are dealing with potentially large result sets.
SSDictCursor
Like SSCursor except it returns rows as dictionaries.

Embedded Server

Instead of connecting to a stand-alone server over the network, the embedded server support lets you run a full server right in your Python code or application server.

If you have built MySQLdb with embedded server support, there are two additional functions you will need to make use of:

server_init(args, groups)

Initialize embedded server. If this client is not linked against the embedded server library, this function does nothing.

args
sequence of command-line arguments
groups
sequence of groups to use in defaults files
server_end()
Shut down embedded server. If not using an embedded server, this does nothing.

See the MySQL documentation for more information on the embedded server.

Title: MySQLdb: a Python interface for MySQL
Author: Andy Dustman
Version: $Revision: 421 $


seal 2010-05-17 23:56 發表評論
]]>
簡明 Python 編程規范(轉)http://www.aygfsteel.com/sealyu/archive/2010/05/14/320937.htmlsealsealThu, 13 May 2010 18:59:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/05/14/320937.htmlhttp://www.aygfsteel.com/sealyu/comments/320937.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/05/14/320937.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/320937.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/320937.htmlhttp://blog.csdn.net/lanphaday,如蒙轉載,必須保留全文完整,未經本人同意,不得用于商業目的。

簡明 Python 編程規范51Testing軟件測試網!L2kA c(M}&k("

編 碼51Testing軟件測試網3EFD`G Xm

    所有的 Python 腳本文件都應在文件頭標上 # -*- coding:utf-8 -*- 。設置編輯器,默認保存為 utf-8 格式。51Testing軟件測試網3}f n9u5@h'uC9?~

注 釋51Testing軟件測試網 K4@?IC J {)b"k"

    業界普遍認同 Python 的注釋分為兩種的概念,一種是由 # 開頭的“真正的”注釋,另一種是 docstrings。前者表明為何選擇當前實現以及這種實現的原理和難點,后者表明如何使用這個包、模塊、類、函數(方法),甚至包括使用示例和單元測試
    堅持適當注釋原則。對不存在技術難點的代碼堅持不注釋,對存在技術難點的代碼必須注釋。但與注釋不同,推薦對每一個包、模塊、類、函數(方法)寫 docstrings,除非代碼一目了然,非常簡單。51Testing軟件測試網 'Y:w2S%ao(_)Lk

縮 進51Testing軟件測試網J?g} G-`5U Gs'Hq

    Python 依賴縮進來確定代碼塊的層次,行首空白符主要有兩種:tab 和空格,但嚴禁兩者混用。如果使用 tab 縮進,設定 tab 為 4 個空格。
    公司內部推薦使用 4 個空格的 tab 進行縮進。51Testing軟件測試網-j a `+z ~r.oQ Zs
空格

    空格在 Python 代碼中是有意義的,因為 Python 的語法依賴于縮進,在行首的空格稱為前導空格。在這一節不討論前導空格相關的內容,只討論非前導空格。非前導空格在 Python 代碼中沒有意義,但適當地加入非前導空格可以增進代碼的可讀性。
MmO x nYM01) 在二元算術、邏輯運算符前后加空格:如 a = b + c;
2) 在一元前綴運算符后不加空格,如 if !flg: pass;
3) “:” 用在行尾時前后皆不加空格,如分枝、循環、函數和類定義語言;用在非行尾時兩端加空格,如 dict 對象的定義 d = {‘key’ : ’value’}。
4) 括 號(含圓括號、方括號和花括號)前后不加空格,如 do_something(arg1, arg2),而不是 do_something( arg1, arg2 );
5) 逗號后面 加一個空格,前面不加空格;s

E'M/z Yv"v lh0空行

    適當的空行有利于增加代碼的可讀性,加空行可以參考如下幾個準則:
1) 在 類、函數的定義間加空行;
2) 在 import 不同種類的模塊間加工行;51Testing軟件測試網L7[2e N+S rm
3) 在函數中的邏輯段落間加空行,即把相關的代碼緊湊寫在一起,作為一個邏輯段落,段落間以空行分隔;

斷行
 
  盡管現在的寬屏顯示器已經可以單屏顯示超過 256 列字符,但本規范仍然堅持行的最大長度不得超過 78 個字符的標準。折疊長行的方法有以下幾種方法:
f?k c&nJ4nR01) 為長變量名換一個短名,如:
    this.is.a.very.long.variable_name = this.is.another.long.variable_name
    應改為:
    variable_name1 = this.is.a.very.long.variable_name51Testing軟件測試網M a cb5"8`1X{
    variable_name2 = this.is.another.variable_name
,_JE9@ p0    variable_name1 = variable_name2s
2) 在括號(包括圓括號、方括號和花括號)內換行,如:51Testing軟件測試網+y ?"Mqe:X$Ylr Q*S
    class Edit(CBase):
U"2|u!? C?Y0        def __init__(self, parent, width, 51Testing軟件測試網m-dN,u b fa(I y
                                font = FONT, color = BLACK, pos = POS, style = 0):
QK/IpVh&HB!c:f r0    或:
x"B}Qm hf!E0    very_very_very_long_variable_name = Edit(parent, "
                                                                            width, "
                                                                            font, "
                                                                            color, "
2r8o,V O#}`.GS?S/B0                                                                            pos)
    如果行長到連第一個括號內的參數都放不下,則每個元素都單獨占一行:51Testing軟件 測試網,kTP"D/ux4af
    very_very_very_long_variable_name = ui.widgets.Edit( "51Testing軟件測試網g5lj"I. {6~z1t
                                                                                    panrent, "
                                                                                    width, "
                                                                                    font, "
                                                                                    color, "
                                                                                    pos)
3) 在長行加入續行符強行斷 行,斷行的位置應在操作符前,且換行后多一個縮進,以使維護人員看代碼的時候看到代碼行首即可判定這里存在換行,如:
8_ V,w)j-mn@-j0if color == WHITE or color == BLACK "
or color == BLUE: # 注意 or 操作符在新行的行首而不是舊行的行尾
do_something(color);

命名
51Testing 軟件測試網/"Xq5|E%Kn

    一致的命名可以給開發人員減少許多麻煩,而恰如其分的命名則可以大幅提高代碼的可讀性,降低維護成本。

常量


 常 量名所有字母大寫,由下劃線連接各個單詞,如51Testing軟件測試網9Nh#f y+{'X^1W
WHITE = 0XFFFFFF51Testing 軟件測試網EiS!| E"i
THIS_IS_A_CONSTANT = 1

變量
51Testing 軟件測試網I Vk6w,|

    變量名全部小寫,由下劃線連接各個單詞,如
color = WHITE51Testing軟件測試網*v-]1m,g"js [Xu'@
this_is_a_variable = 1
R$K so M~D.C0    不論是類成員變量還是全局變量,均不使用 m 或 g 前綴。私有類成員使用單一下劃線前綴標識,多定義公開成員,少定義私有成員。51Testing 軟件測試網tlF e.v;Ym!Wg?
    變量名不應帶有類型信息,因為 Python 是動態類型語言。如 iValue、names_list、dict_obj 等都是不好的命名。51Testing 軟件測試網N"z:p2};J&`

函 數

Cloqn0
    函數名的命名規則與變量名相同。
U4lu b"0
-s2w9yym;{ P0    類名單詞首字母大寫,不使用下劃線連接單詞,也不加入 C、T 等前綴。如:
class ThisIsAClass(object):
    passs
模塊51Testing軟件測試網GK!P }:D"x
    模塊名全部小寫,對于包內使用的模塊,可以加一個下劃線前綴,如
module.py
_internal_module.py

51Testing軟件測試網5zK b.S })W#H M+_

    包的命名規范與模塊相同。

縮寫


    命名應當盡量使用全拼寫的單詞,縮寫的情況有如下兩種:
1) 常用的縮寫,如 XML、ID等,在命名時也應只大寫首字母,如
class XmlParser(object):pass51Testing軟件測試網8xYp qM5?
2) 命名中含有長單詞,對某個單詞進行縮寫。這時應使用約定成俗的縮寫方式,如去除元音、包含輔音的首字符等方式, 例如:
2E@E+y BD}p,d0function 縮寫為 fn51Testing軟件 測試網e9F+^z{ q7T A
text 縮寫為 txt51Testing 軟件測試網A'U~OwjE*i
object 縮寫為 obj
count 縮寫為 cnt
number 縮寫為 num,等。
特定命名方 式
    主要是指 __xxx__ 形式的系統保留字命名法。項目中也可以使用這種命名,它的意義在于這種形式的變量是只讀的,這種形式的類成員函數盡量不要重載。如
class Base(object):
    def __init__(self, id, parent = None):
        self.__id__ = id
        self.__parent__ = parent51Testing軟件測試網 3v3M?km#]L]*L m2D
    def __message__(self, msgid):
        # …略
其中 __id__、__parent__ 和 __message__ 都采用了系統保留字命名法。51Testing軟件測試網2V D_ nf?X"

語 句
51Testing軟件測試網&v`?Y z7za o

import

    import 語句有以下幾個原則需要遵守:51Testing軟件測試網N}D~@E J0F:}v.i
1) import 的次序,先 import Python 內置模塊,再 import 第三方模塊,最后 import 自己開發的項目中的其 它模塊;這幾種模塊中用空行分隔開來。51Testing 軟件測試網 r"l ~J3E%B6BVH
2) 一條 import 語句 import 一個模塊。
3) 當從模塊中 import 多個對象且超過一行時,使用如下斷行法(此語法 py2.5 以上版本才支持):51Testing 軟件測試網)^he$i+RMV'B
from module import (obj1, obj2, obj3, obj4,
                                    obj5, obj6)
4) 不 要使用 from module import *,除非是 import 常量定義模塊或其它你確保不會出現命名空間沖突的模塊。
";wf4a4D WaS$c@ ~0賦值
    對于賦值語言,主要是不要做無謂的對齊,如:
Y0t&V6U(Qxx?vHQv1c0a   = 1     # 這是一個行注釋
variable  = 2     # 另一個行注釋
fn   = callback_function  # 還是行注釋51Testing軟件測試網+l q rq Z-n&_-`*[l P5[
沒有必要做這種對齊,原因有兩點:一是這種對齊會打亂編程時的注意力,大腦要同時處理兩件 事(編程和對齊);二是以后閱讀和維護都很困難,因為人眼的橫向視野很窄,把三個字段看成一行很困難,而且維護時要增加一個更長的變量名也會破壞對齊。直 接這樣寫為佳:
a = 1 # 這是一個行注釋
variable = 2 # 另一個行注釋
fn = callback_function # 還是行注釋
6X!_I%J+L ?K0分枝和循環
    對于分枝和循環,有如下幾點需要注意的:
1) 不 要寫成一行,如:
if !flg: pass 和 for i in xrange(10): print i都不是好代碼,應寫成
if !flg:
    pass
for i in xrange(10):
    print i
注: 本文檔中出現寫成一行的例子是因為排版的原因,不得作為編碼中不斷行的依據。
2) 條 件表達式的編寫應該足夠 pythonic,如以下形式的條件表達式是拙劣的:51Testing 軟件測試網,F!EH ~Wr]
if len(alist) != 0: do_something()
if alist != []: do_something()
if s != “”: do_something()
8z-Y[ F2F0if var != None: do_something()
if var != False: do_something()
上面的語句應該寫成:
if seq: do_somethin() # 注意,這里命名也更改了
if var: do_something()
3) 用 得著的時候多使用循環語句的 else 分句,以簡化代碼。51Testing軟件測試網 q _?}6o4t-S2sZ

已有代碼
51Testing軟件測試網 O8|c px*N2evNK D

    對于項目中已有的代碼,可能因為歷史遺留原因不符合本規范,應當看作可以容忍的特例,允許存在;但不應在新的代碼中延續舊的風格。
    對于第三方模塊,可能不符合本規范,也應看作可以容忍的特例,允許存在;但不應在新的代碼中使用第三方模塊的風格。
    tab 與空格混用的縮進是不可容忍的,在運行項目時應使用 –t 或 –tt 選項排查這種可能性存在。出現混用的情況時,如果是公司開發的基礎類庫代碼,應當通知類庫維護人員修改;第三方模塊則可以通過提交 patch 等方式敦促開發者修正問題。

已有風格


    開發人員往往在加入項目之前已經形成自有的編碼風格,加入項目后應以本規范為準編寫代碼。特別是匈牙利命名法,因為帶有類型信息,并不適合 Python 編程,不應在 Python 項目中應用。

seal 2010-05-14 02:59 發表評論
]]>
Django Google Maps form widget(轉)http://www.aygfsteel.com/sealyu/archive/2010/05/11/320542.htmlsealsealMon, 10 May 2010 19:42:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/05/11/320542.htmlhttp://www.aygfsteel.com/sealyu/comments/320542.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/05/11/320542.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/320542.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/320542.htmlWe’re building a Django application at work, and I had to implement a way for a user to select a location on a map, in order to be able to save the exact coordinates and the zoom level the user chose.
I looked around to see if something similar had been developed, but I did not find anything so simple and useful as what I later developed, so for the sake of open source-ness I’m sharing it here with you.
It is implemented as a standard Django form widget so just do as any other Django widget, for example:

class PersonForm(forms.Form):
name = forms.CharField()
website = forms.URLField()
location = forms.CharField(widget=GMapInput(attrs={'width':'600', 'height':'400'}))

Here’s the code for the GMapInput class (sorry for the docs in Spanish, but I’m in Mexico):

from django.forms.widgets import Input
from django.utils.safestring import mark_safe
 
class GMapInput(Input):
"""
Widget para seleccionar un punto en un mapa de Google
"""

 
def render(self, name, value, attrs=None):
"""
Atributos extras:
- width: ancho del mapa en pixeles
- height: alto del mapa en pixeles
- center: latitud,longitud del punto central del mapa
- zoom: zoom inicial del mapa, 1 - 17
"""

 
final_attrs = self.build_attrs(attrs)
width = final_attrs['width'] if 'width' in final_attrs else '500'
height = final_attrs['height'] if 'height' in final_attrs else '300'
center = final_attrs['center'] if 'center' in final_attrs else '21.983801,-100.964355' # Centro de México
zoom = final_attrs['zoom'] if 'zoom' in final_attrs else '4' # Zoom amplio, se ve todo un país
 
widget = u'''<div style="margin-left:7em; padding-left:30px;">
<input type="hidden" value="%(value)s" name="%(name)s" id="%(id)s" />
<div id="%(id)s_map" style="width: %(width)spx; height: %(height)spx"></div></div>
<script type="text/javascript">
var %(id)s_map = new GMap2(document.getElementById("%(id)s_map"));
%(id)s_map.addControl(new GLargeMapControl3D());
 
var %(id)s_marker;
function %(id)s_updateField() {
document.getElementById("%(id)s").value = %(id)s_marker.getLatLng().toUrlValue() + "|" + %(id)s_map.getZoom();
%(id)s_map.panTo(%(id)s_marker.getLatLng(), true);
}
'
'' % { 'value': value, 'name': name, 'id': final_attrs['id'], 'width': width, 'height': height }
 
if value is None or value == '':
widget = widget + u'''
%(id)s_map.setCenter(new GLatLng(%(center)s), %(zoom)s);
var %(id)s_clickListener = GEvent.addListener(%(id)s_map, "click", function(overlay, latlng) {
if(latlng) {
%(id)s_marker = new GMarker(latlng, {draggable: true});
%(id)s_map.addOverlay(%(id)s_marker);
%(id)s_updateField();
 
GEvent.addListener(%(id)s_marker, "dragend", %(id)s_updateField);
GEvent.addListener(%(id)s_map, "zoomend", %(id)s_updateField);
GEvent.addListener(%(id)s_map, "dblclick", function (overlay, latlng) { %(id)s_marker.setLatLng(latlng); %(id)s_updateField(); });
GEvent.removeListener(%(id)s_clickListener);
}
});
</script>'
'' % { 'id': final_attrs['id'], 'center': center, 'zoom': zoom }
else:
values = value.partition('|')
 
widget = widget + u'''
%(id)s_map.setCenter(new GLatLng(%(coords)s), %(zoom)s);
%(id)s_marker = new GMarker(new GLatLng(%(coords)s), {draggable: true});
%(id)s_map.addOverlay(%(id)s_marker);
 
GEvent.addListener(%(id)s_marker, "dragend", %(id)s_updateField);
GEvent.addListener(%(id)s_map, "zoomend", %(id)s_updateField);
GEvent.addListener(%(id)s_map, "dblclick", function (overlay, latlng) { %(id)s_marker.setLatLng(latlng); %(id)s_updateField(); });
'
'' % { 'id': final_attrs['id'], 'coords': values[0], 'zoom': values[2] }
 
return mark_safe(widget)

Don’t forget to add the <script> tag linking to the Google Maps API.

It is yet far from perfect, but I still hope it helps someone out there.



seal 2010-05-11 03:42 發表評論
]]>
支持Django的主機列表(轉)http://www.aygfsteel.com/sealyu/archive/2010/05/11/320539.htmlsealsealMon, 10 May 2010 17:14:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/05/11/320539.htmlhttp://www.aygfsteel.com/sealyu/comments/320539.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/05/11/320539.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/320539.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/320539.html
webfaction.com 
dreamhost.com
theplanet.com
nextlevelinternet.com
textdrive.com
rackspace.net
datotel.com
ovh.net
serverbeach.com
secureserver.net
nac.net
eli.net
oneandone.net
gypsyhosting.com
xlquest.net
vpslink.com
recrutae.net
dallas-datacenter.com
carohosting.com
rimuhosting.com

seal 2010-05-11 01:14 發表評論
]]>
發布一個DJANGO的論壇系統LBFORUM(開源、帶演示)(轉)http://www.aygfsteel.com/sealyu/archive/2010/03/29/316844.htmlsealsealMon, 29 Mar 2010 08:30:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/03/29/316844.htmlhttp://www.aygfsteel.com/sealyu/comments/316844.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/03/29/316844.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/316844.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/316844.html

簡介

LBForum 用django開發的論壇系統,演示地址為:http://vik.haoluobo.com/lbforum/ 
項目的地址為:http://github.com/vicalloy/LBForum 
界面部分抄的 FluxBB(一個開源的PHP論壇 http://fluxbb.org/ )。 
雖然Django寫的論壇也不少,不過還真沒什么好用的。 
大多Django論壇都是獨立的app,而且不少還缺模板,想我這樣有經驗的Django用戶要跑起來都覺得麻煩,其他普通用戶就更別說了。 
LBForum主要注重部署的方便性和易用性,功能方面目前還比較簡單。 
LBForum一開始就是以整站的形式提供,所以以LBForum做為基礎項目進行二次開發是很容易的。 
同時LBForum的開發盡量遵照Django可復用app原則,因此即使需要將LBForum做為獨立的app集成到其他項目也并不會太難。

主要功能

目前功能還比較簡單,而且還有些小問題有待修正。

  1. 論壇分類,分版塊
  2. 發帖,回帖
  3. BBCode支持
  4. 置頂貼
  5. 使用django admin提供論壇管理功能

用開發服務器把LBForum跑起來

  1. 先把代碼down下來。LBForum托管在github上,http://github.com/vicalloy/LBForum 。如果你沒有安裝git,你可以直接用界面右上方的download 
    source功能下載代碼。
  2. 運行"scripts"create_lbforum_env.py初始化lbforum的python虛擬環境。該腳本會自動創建一個python的虛擬環境并使用easy_install安裝對應的依賴包,同時將一些依賴包解壓到對應的目錄中。 
    注:django使用的是svn版本,所以機器上必須要安裝有SVN,不然腳本會運行失敗。如果因為由于svn的問題導致腳本運行失敗,可以運行lbforum_env.bat進入lbforum環境,手動安裝django的svn版本。
  3. 環境初始化好后,運行lbforum_env.bat進入lbforum環境
  4. 運行%mg% syncdb初始化數據庫
  5. 運行%mg% runserver啟動django開發服務器
  6. 進入admin,創建論壇分類和版塊
  7. 進入版塊發帖

LBForum的目錄結構說明

|+lbforum_env/#lbforum運行的python虛擬環境,運行create_lbforum_env.py后自動創建 
|+requirements/#lbforum用的第三方庫和app,運行的時候會將該目錄加到python路徑 
|~scripts/#工程相關腳本 
| |-create_lbforum_env.py#初始化python虛擬環境,并自動安裝easy_install/django依賴庫 
| |-helper.py#提供其他腳本所需的輔助函數 
| `-lbforum_env.bat*#啟動lbforum運行的虛擬環境及,并為lbforum的manage.py提供快捷方式%mg%,比如初始化數據庫%mg% 
syncdb 
|~sites/#站點配置/模板/靜態文件 
| `~default/#默認站點 
|   |+static/#靜態資源文件,如css等 
|   |+templates/#Django模板目錄 
|   |+templates_plus/#Django模板目錄,用戶將自己重寫過的目標放到該目錄 
|   `-…… 
|~src/#django的app目錄 
| |+account/#account相關app。具體站點通常會對用戶中心進行定制,所以該app在實際應用中很可能需要針對實際情況進行修改。 
| |+djangohelper/#一些django的輔助函數等, 
| |+lbforum/#lbforum的主app,論壇功能都在改app中 
| |+lbregistration/#registration app的lbforum擴展,主要去掉郵件地址認證功能 
| |+onlineuser/#顯示在線用戶的app(可復用的django app,可脫離lbforum單獨使用)
| `+simpleavatar/#頭像功能的app(可復用的django app,可脫離lbforum單獨使用,依賴djangohelper) 
|+tools/#工程用到的輔助工具,目前只有一個virtualenv的腳本

注:

  1. 由于計劃在以后做i18n,所以目前只提供英文界面
  2. django的錯誤提示是顯示在字段后面,fluxbb的錯誤全部都顯示在表單前面。由于模板沒有調好,所以目前按照fluxbb的方式顯示錯誤,所以錯誤顯示有些不太正常。
  3. bbcode的輸入框本想做成自適應大小的,不過也調得有些問題,所以現在輸入框的大小固定。
  4. 文檔… ,感覺好難寫-_-,目前文檔不全(項目中沒有帶任何的文檔),日后補上。
  5. 應用程序的目錄結構主要查看pinax
  6. simpleavatar模塊部分代碼來自django-avatar
  7. 依賴包除用easy_install在線安裝的外,盡量使用zip包的方式附帶在項目中,減少安裝依賴包的困難。
  8. 遠程部署腳本計劃使用fabric,但fabric本身安裝比較麻煩,所暫未處理。
  9. 項目最早放在googlecode,不過感覺github的功能更強些,所以移了過去。


seal 2010-03-29 16:30 發表評論
]]>
Python IDE--Wing IDE的安裝和破解(轉)http://www.aygfsteel.com/sealyu/archive/2009/09/28/296734.htmlsealsealMon, 28 Sep 2009 02:09:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/28/296734.htmlhttp://www.aygfsteel.com/sealyu/comments/296734.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/28/296734.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/296734.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/296734.html以下內容針對wingIDE 3系列,并且在3.1.6版本測試通過。

不過,wingIDE對中文的支持好像有問題,在我這里,中文全部顯示成了方框。

激活的過程還有些麻煩:

1、將解壓后的WingIDE.exe 和Python25.dll Copy到安裝目錄的Bin下;

2、運行wing3.X,出現license窗口,輸入類似這樣的字符CNxxx-xxxxx-xxxxx-xxxxx (x =1-9);點擊“continus”,如下圖(圖中最后多了一個數字3);

3、copy wingIDE License文件提示中的request No,如下圖:

4、打開cmd,cd到wingIDE安裝目錄下的bin目錄,運行wingide.exe,按照提示輸入CNxxx-xxxxx-xxxxx-xxxxx(步驟2中輸入的序列號)和步驟3中的request code,并按照提示輸入你使用的操作系統,如下圖:

5、將步驟4中生成的activation code:填入步驟3的提示框中,就成功破解了wingIDE

wingIDE professional下載地址:

http://wingware.com/downloads/wingide/

wingIDE professional破解文件:

wingide-crack



seal 2009-09-28 10:09 發表評論
]]>
django中的一個選擇時間的widgethttp://www.aygfsteel.com/sealyu/archive/2009/09/28/296714.htmlsealsealMon, 28 Sep 2009 00:54:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/28/296714.htmlhttp://www.aygfsteel.com/sealyu/comments/296714.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/28/296714.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/296714.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/296714.htmlThis snippet defines a Widget that is very similar to the SelectDateWidget located in django.forms.extras.widgets. The main difference however is that it works with Times instead of Dates.

The SelectTimeWidget supports both 24-hr and 12-hr formats, and flexible time increments for hours, minutes and seconds. Sample usage is illustrated below:

# Specify a basic 24-hr time Widget (the default)
t = forms.TimeField(widget=SelectTimeWidget())

# Force minutes and seconds to be displayed in increments of 10
t = forms.TimeField(widget=SelectTimeWidget(minute_step=10, second_step=10))

# Use a 12-hr time format, which will display a 4th select
# element containing a.m. and p.m. options)
t = forms.TimeField(widget=SelectTimeWidget(twelve_hr=True))

UPDATE: Changed the time pattern to a more precise regular expression, and added the sample usage above.


import re
from django.forms.widgets import Widget, Select, MultiWidget
from django.forms.extras.widgets import SelectDateWidget
from django.utils.safestring import mark_safe

# Attempt to match many time formats:
#
 Example: "12:34:56 P.M."  matches:
#
 ('12', '34', ':56', '56', 'P.M.', 'P', '.', 'M', '.')
#
 ('12', '34', ':56', '56', 'P.M.')
#
 Note that the colon ":" before seconds is optional, but only if seconds are omitted
#
time_pattern = r'(\d\d?):(\d\d)(:(\d\d))? *((a{1}|A{1}|p{1}|P{1})(\.)?(m{1}|M{1})(\.)?)?$'
time_pattern = r'(\d\d?):(\d\d)(:(\d\d))? *([aApP]\.?[mM]\.?)?$' # w/ Magus's suggestions

RE_TIME 
= re.compile(time_pattern)
# The following are just more readable ways to access re.matched groups:
HOURS = 0
MINUTES 
= 1
SECONDS 
= 3
MERIDIEM 
= 4

class SelectTimeWidget(Widget):
    
"""
    A Widget that splits time input into <select> elements.
    Allows form to show as 24hr: <hour>:<minute>:<second>,
    or as 12hr: <hour>:<minute>:<second> <am|pm> 
    
    Also allows user-defined increments for minutes/seconds
    
"""
    hour_field 
= '%s_hour'
    minute_field 
= '%s_minute'
    second_field 
= '%s_second' 
    meridiem_field 
= '%s_meridiem'
    twelve_hr 
= False # Default to 24hr.
    
    
def __init__(self, attrs=None, hour_step=None, minute_step=None, second_step=None, twelve_hr=False):
        
'''
        hour_step, minute_step, second_step are optional step values for
        for the range of values for the associated select element
        twelve_hr: If True, forces the output to be in 12-hr format (rather than 24-hr)
        
'''
        self.attrs 
= attrs or {}
        
        
if twelve_hr:
            self.twelve_hr 
= True # Do 12hr (rather than 24hr)
            self.meridiem_val = 'a.m.' # Default to Morning (A.M.)
        
        
if hour_step and twelve_hr:
            self.hours 
= range(1,13,hour_step) 
        
elif hour_step: # 24hr, with stepping.
            self.hours = range(0,24,hour_step)
        
elif twelve_hr: # 12hr, no stepping
            self.hours = range(1,13)
        
else# 24hr, no stepping
            self.hours = range(0,24

        
if minute_step:
            self.minutes 
= range(0,60,minute_step)
        
else:
            self.minutes 
= range(0,60)

        
if second_step:
            self.seconds 
= range(0,60,second_step)
        
else:
            self.seconds 
= range(0,60)

    
def render(self, name, value, attrs=None):
        
try# try to get time values from a datetime.time object (value)
            hour_val, minute_val, second_val = value.hour, value.minute, value.second
            
if self.twelve_hr:
                
if hour_val >= 12:
                    self.meridiem_val 
= 'p.m.'
                
else:
                    self.meridiem_val 
= 'a.m.'
        
except AttributeError:
            hour_val 
= minute_val = second_val = 0
            
if isinstance(value, basestring):
                match 
= RE_TIME.match(value)
                
if match:
                    time_groups 
= match.groups();
                    hour_val 
= int(time_groups[HOURS]) % 24 # force to range(0-24)
                    minute_val = int(time_groups[MINUTES]) 
                    
if time_groups[SECONDS] is None:
                        second_val 
= 0
                    
else:
                        second_val 
= int(time_groups[SECONDS])
                    
                    
# check to see if meridiem was passed in
                    if time_groups[MERIDIEM] is not None:
                        self.meridiem_val 
= time_groups[MERIDIEM]
                    
else# otherwise, set the meridiem based on the time
                        if self.twelve_hr:
                            
if hour_val >= 12:
                                self.meridiem_val 
= 'p.m.'
                            
else:
                                self.meridiem_val 
= 'a.m.'
                        
else:
                            self.meridiem_val 
= None
                    

        
# If we're doing a 12-hr clock, there will be a meridiem value, so make sure the
        # hours get printed correctly
        if self.twelve_hr and self.meridiem_val:
            
if self.meridiem_val.lower().startswith('p'and hour_val > 12 and hour_val < 24:
                hour_val 
= hour_val % 12
        
elif hour_val == 0:
            hour_val 
= 12
            
        output 
= []
        
if 'id' in self.attrs:
            id_ 
= self.attrs['id']
        
else:
            id_ 
= 'id_%s' % name

        
# NOTE: for times to get displayed correctly, the values MUST be converted to unicode
        # When Select builds a list of options, it checks against Unicode values
        hour_val = u"%.2d" % hour_val
        minute_val 
= u"%.2d" % minute_val
        second_val 
= u"%.2d" % second_val

        hour_choices 
= [("%.2d"%i, "%.2d"%i) for i in self.hours]
        local_attrs 
= self.build_attrs(id=self.hour_field % id_)
        select_html 
= Select(choices=hour_choices).render(self.hour_field % name, hour_val, local_attrs)
        output.append(select_html)

        minute_choices 
= [("%.2d"%i, "%.2d"%i) for i in self.minutes]
        local_attrs[
'id'= self.minute_field % id_
        select_html 
= Select(choices=minute_choices).render(self.minute_field % name, minute_val, local_attrs)
        output.append(select_html)

        second_choices 
= [("%.2d"%i, "%.2d"%i) for i in self.seconds]
        local_attrs[
'id'= self.second_field % id_
        select_html 
= Select(choices=second_choices).render(self.second_field % name, second_val, local_attrs)
        output.append(select_html)
    
        
if self.twelve_hr:
            
#  If we were given an initial value, make sure the correct meridiem get's selected.
            if self.meridiem_val is not None and  self.meridiem_val.startswith('p'):
                    meridiem_choices 
= [('p.m.','p.m.'), ('a.m.','a.m.')]
            
else:
                meridiem_choices 
= [('a.m.','a.m.'), ('p.m.','p.m.')]

            local_attrs[
'id'= local_attrs['id'= self.meridiem_field % id_
            select_html 
= Select(choices=meridiem_choices).render(self.meridiem_field % name, self.meridiem_val, local_attrs)
            output.append(select_html)

        
return mark_safe(u'\n'.join(output))

    
def id_for_label(self, id_):
        
return '%s_hour' % id_
    id_for_label 
= classmethod(id_for_label)

    
def value_from_datadict(self, data, files, name):
        
# if there's not h:m:s data, assume zero:
        h = data.get(self.hour_field % name, 0) # hour
        m = data.get(self.minute_field % name, 0) # minute 
        s = data.get(self.second_field % name, 0) # second

        meridiem 
= data.get(self.meridiem_field % name, None)

        
#NOTE: if meridiem IS None, assume 24-hr
        if meridiem is not None:
            
if meridiem.lower().startswith('p'and int(h) != 12:
                h 
= (int(h)+12)%24 
            
elif meridiem.lower().startswith('a'and int(h) == 12:
                h 
= 0
        
        
if (int(h) == 0 or h) and m and s:
            
return '%s:%s:%s' % (h, m, s)

        
return data.get(name, None)


seal 2009-09-28 08:54 發表評論
]]>
django form的widgets類型列表http://www.aygfsteel.com/sealyu/archive/2009/09/27/296644.htmlsealsealSun, 27 Sep 2009 07:35:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/27/296644.htmlhttp://www.aygfsteel.com/sealyu/comments/296644.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/27/296644.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/296644.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/296644.htmlWidgets

A widget is Django’s representation of a HTML input element. The widget handles the rendering of the HTML, and the extraction of data from a GET/POST dictionary that corresponds to the widget.

Django provides a representation of all the basic HTML widgets, plus some commonly used groups of widgets:

class TextInput
Text input: <input type='text' ...>
class PasswordInput

Password input: <input type='password' ...>

Takes one optional argument:

render_value
Determines whether the widget will have a value filled in when the form is re-displayed after a validation error (default is True).
class HiddenInput
Hidden input: <input type='hidden' ...>
class MultipleHiddenInput
Multiple <input type='hidden' ...> widgets.
class FileInput
File upload input: <input type='file' ...>
class DateInput
New in Django 1.1: Please, see the release notes

Date input as a simple text box: <input type='text' ...>

Takes one optional argument:

format
The format in which this field’s initial value will be displayed.

If no format argument is provided, the default format is '%Y-%m-%d'.

class DateTimeInput
New in Django 1.0: Please, see the release notes

Date/time input as a simple text box: <input type='text' ...>

Takes one optional argument:

format
The format in which this field’s initial value will be displayed.

If no format argument is provided, the default format is '%Y-%m-%d %H:%M:%S'.

class TimeInput

Time input as a simple text box: <input type='text' ...>

Takes one optional argument:

format
The format in which this field’s initial value will be displayed.

If no format argument is provided, the default format is '%H:%M:%S'.

Changed in Django 1.1: The format argument was not supported in Django 1.0.
class Textarea
Text area: <textarea>...</textarea>
class CheckboxInput

Checkbox: <input type='checkbox' ...>

Takes one optional argument:

check_test
A callable that takes the value of the CheckBoxInput and returns True if the checkbox should be checked for that value.
class Select

Select widget: <select><option ...>...</select>

Requires that your field provides choices.

class NullBooleanSelect
Select widget with options ‘Unknown’, ‘Yes’ and ‘No’
class SelectMultiple

Select widget allowing multiple selection: <select multiple='multiple'>...</select>

Requires that your field provides choices.

class RadioSelect

A list of radio buttons:

<ul>
<li><input type='radio' ...></li>
...
</ul>

Requires that your field provides choices.

class CheckboxSelectMultiple

A list of checkboxes:

<ul>
<li><input type='checkbox' ...></li>
...
</ul>
class MultiWidget
Wrapper around multiple other widgets
class SplitDateTimeWidget

Wrapper around two widgets: DateInput for the date, and TimeInput for the time.

Takes two optional arguments, date_format and time_format, which work just like the format argument for DateInput and TimeInput.

Changed in Django 1.1: The date_format and time_format arguments were not supported in Django 1.0.
class SelectDateWidget

Wrapper around three select widgets: one each for month, day, and year. Note that this widget lives in a separate file from the standard widgets.

from django.forms.extras.widgets import SelectDateWidget

date = forms.DateField(widget=SelectDateWidget())

Specifying widgets

Form.widget

Whenever you specify a field on a form, Django will use a default widget that is appropriate to the type of data that is to be displayed. To find which widget is used on which field, see the documentation for the built-in Field classes.

However, if you want to use a different widget for a field, you can - just use the 'widget' argument on the field definition. For example:

from django import forms

class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)

This would specify a form with a comment that uses a larger Textarea widget, rather than the default TextInput widget.

Customizing widget instances

When Django renders a widget as HTML, it only renders the bare minimum HTML - Django doesn't add a class definition, or any other widget-specific attributes. This means that all 'TextInput' widgets will appear the same on your web page.

If you want to make one widget look different to another, you need to specify additional attributes for each widget. When you specify a widget, you can provide a list of attributes that will be added to the rendered HTML for the widget.

For example, take the following simple form:

class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField()

This form will include three default TextInput widgets, with default rendering - no CSS class, no extra attributes. This means that the input boxes provided for each widget will be rendered exactly the same:

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>

On a real web page, you probably don't want every widget to look the same. You might want a larger input element for the comment, and you might want the 'name' widget to have some special CSS class. To do this, you use the attrs argument when creating the widget:

Widget.attrs

For example:

class CommentForm(forms.Form):
name = forms.CharField(
widget=forms.TextInput(attrs={'class':'special'}))
url = forms.URLField()
comment = forms.CharField(
widget=forms.TextInput(attrs={'size':'40'}))

Django will then include the extra attributes in the rendered output:

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>


seal 2009-09-27 15:35 發表評論
]]>
django jquery ajax 的一個小例子http://www.aygfsteel.com/sealyu/archive/2009/09/24/296229.htmlsealsealThu, 24 Sep 2009 00:51:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/24/296229.htmlhttp://www.aygfsteel.com/sealyu/comments/296229.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/24/296229.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/296229.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/296229.html

Using Django templates with jQuery AJAX

2009 January 6
by Nizam

I recently discovered a neat way of displaying data retrieved using jquery AJAX in concert with Django’s template engine. You can create a view in Django which simply uses the render_to_response shortcut function to render the results server-side and then just use jquery.load to dynamically fetch the results.

Eventhough, returning some raw JSON data is much more efficient as far as bandwidth is concerned, method is a lot simpler.

I have been using jquery for over a year now. I have found that its built-in DOM manipulation features are a bit limited, especially for manipulating tables (e.g., adding rows dynamically). This method is much cleaner than doing all that DOM manipulation.

Here is all the jQuery code to handle the search and AJAX spinner display:

01.$( document ).ready( function() {
02.    $( '#searchSubmit' ).click( function() {
03.        q = $( '#q' ).val();
04.        $( '#results' ).html( '&nbsp;' ).load(
05.                    '{% url demo_user_search %}?q=' + q );
06.    });
07.});
08. 
09.$( document ).ajaxStart( function() {
10.    $( '#spinner' ).show();
11.}).ajaxStop( function() {
12.    $( '#spinner' ).hide();
13.});

Here is the Django view function that does the heavy lifting on the server-side:

01.def ajax_user_search( request ):
02.    if request.is_ajax():
03.        q = request.GET.get( 'q' )
04.        if q is not None:
05.            results = User.objects.filter(
06.                Q( first_name__contains = q ) |
07.                Q( last_name__contains = q ) |
08.                Q( username__contains = q ) ).order_by( 'username' )
09. 
10.            template = 'results.html'
11.            data = {
12.                'results': results,
13.            }
14.            return render_to_response( template, data,
15.                context_instance = RequestContext( request ) )

Here are some screenshots of the results:

AJAX operation in progress

AJAX operation in progress

Returned results

Returned results

No results

No results

The sample Django project is included for your perusal and is released under the MIT license. I used the excellent Aptana Studio IDE when working on this demo so it can be imported straight into it as an Aptana project.

Download ajax_user_list.zip



seal 2009-09-24 08:51 發表評論
]]>
django form的field類型列表http://www.aygfsteel.com/sealyu/archive/2009/09/23/296173.htmlsealsealWed, 23 Sep 2009 07:18:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/23/296173.htmlhttp://www.aygfsteel.com/sealyu/comments/296173.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/23/296173.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/296173.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/296173.html閱讀全文

seal 2009-09-23 15:18 發表評論
]]>
django modal的field類型列表http://www.aygfsteel.com/sealyu/archive/2009/09/11/294748.htmlsealsealFri, 11 Sep 2009 08:10:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/11/294748.htmlhttp://www.aygfsteel.com/sealyu/comments/294748.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/11/294748.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/294748.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/294748.html閱讀全文

seal 2009-09-11 16:10 發表評論
]]>
django生成po文件時出現的xgettext的錯誤 (轉) http://www.aygfsteel.com/sealyu/archive/2009/09/10/294535.htmlsealsealThu, 10 Sep 2009 02:18:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/09/10/294535.htmlhttp://www.aygfsteel.com/sealyu/comments/294535.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/09/10/294535.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/294535.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/294535.html通過摸索和查閱django官網文檔,我今天已經解決windows上執行django-admin.py makemessages -l zh_CN 后出現'xgettext'不是內部或外部命令,也不是可運行的程序或批處理文件的錯誤

原因和解決辦法是:

分析django的源代碼中關于國際化方面的(makemessages)就知道,上述命令最終調用的是os.cmd之類調用命令行的東西,而 windows的path路徑列表中沒有xgettext.exe,這是因為windows上沒有gettext,所以要安裝 gettext(python有gettext,但是好像不行,它沒有xgettext)
下載地址是:http://sourceforge.net/projects/gettext
下載這三個:
gettext-runtime-X.bin.woe32.zip 
gettext-tools-X.bin.woe32.zip 
libiconv-X.bin.woe32.zip 

解壓這3個zip文件到同一個文件夾,比如 C:"Program Files"gettext-utils 
然后添加到系統變量的PATH中:
控制面板 > 系統 > 高級 > 環境變量
在系統變量列表中, 選中Path, 然后單擊編輯 
添加 ;C:"Program Files"gettext-utils"bin 到結尾后一直點確定就行了

  
那3個文件全部選中后,直接用winrar解壓,選擇一個目錄后解壓即可



seal 2009-09-10 10:18 發表評論
]]>
Intro to Unintrusive JavaScript with Djangohttp://www.aygfsteel.com/sealyu/archive/2009/08/29/293132.htmlsealsealSat, 29 Aug 2009 14:53:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/08/29/293132.htmlhttp://www.aygfsteel.com/sealyu/comments/293132.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/08/29/293132.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/293132.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/293132.html閱讀全文

seal 2009-08-29 22:53 發表評論
]]>
Django和Ajax教程(轉)http://www.aygfsteel.com/sealyu/archive/2009/08/29/293131.htmlsealsealSat, 29 Aug 2009 14:51:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/08/29/293131.htmlhttp://www.aygfsteel.com/sealyu/comments/293131.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/08/29/293131.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/293131.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/293131.html閱讀全文

seal 2009-08-29 22:51 發表評論
]]>
Django資源大全(轉)http://www.aygfsteel.com/sealyu/archive/2009/08/21/292164.htmlsealsealFri, 21 Aug 2009 13:54:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/08/21/292164.htmlhttp://www.aygfsteel.com/sealyu/comments/292164.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/08/21/292164.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/292164.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/292164.html
以前整理的django資源列表,從我的wiki上轉過來的。

要找django資源,官網的wiki也是一個不錯的地方。

http://code.djangoproject.com/wiki/DjangoResources
資源

    * django官網
    * django文檔
    * Django Step by Step 曾是最佳的django入門教程,只是這個教程是針對0.95的,現在不少地方已經有所變動。
    * django可復用app設計
    * django最佳實踐 django可復用app設計 的一個更好的分支。個人為人這個文檔是每個django開發人員必讀的。
    * django最佳實踐 中文翻譯
    * django book 一本免費的django電子書
    * django book 中文翻譯
    * djangosnippets 一個關于django的代碼片段網站,在里面可以找到一些應用的django代碼片段。站點本身是用django寫的,且開發源碼。
    * djangosites 這個網站里介紹了很多實用django搭建的站點。而且可以從這里找到很多帶源代碼的django站點。不過我個人覺得里面沒有多少值得參考的站點代碼。

使用django搭建的站點

    * django官網 django官網本身使用django搭建,而其提供了代碼。django官網的大多功能由整合的trac實現,所以網站的django代碼沒幾行。
    * 海報網 據說這是目前流量最大的django站點。據我的了解,這個網站的流量也確實大的有些超乎想象,該網站應當有接近CSDN的流量。不過這個網站將大量的頁面進行了靜態化,如果以這個網站的標準來評價django的性能應當不夠客觀。
    * 好看簿 國內的另一個django站點,目前也有不錯的流量。作為該網站的用戶,我感覺網站的響應速度并不怎么快??磥砗每床驹诜掌鲀灮矫孢€需要更多的努力。

django的開源項目

    * pinax 這是我看到的最有價值的django開源項目。pinax可以看做是django的一個腳手架。她提供了快速開始一個新django項目的方法,同時對大量第三方app的使用方法進行了演示。django的app質量參差不齊,如果你想挑選app,那你可以看看pinax里都集成了哪些app。pinax 里集成了的app通常都不至于太爛。此外pinax自身也帶了一些有用的app,比如blog等。
      如果你想以最快的速度了解pinax,可以去 http://cloud27.com/ 看看。這是一個用pinax搭建的SNS網站。
    * Satchmo 網店系統??此慕榻B,似乎已經有不少人在用這東西了。
    * LFS(Lightning Fast Shop) 網店系統,就Demo來看似乎是傾向于房屋交易平臺。陸陸續續的也有部分商業網站開始使用該系統了,比如這個。
    * reviewboard 非常有前途的一個code review工具。最開始是VMware在用,來后給開源了。

django的可重用app
CMS

    * Django CMS Apps Comparison Django CMS Apps的比較

Forum

    * Django Forum Apps Comparison Django Forum Apps的比較

調試

    * django-debug-toolbar 為django站點增加調試功能,支持查看django生成的sql語句,及sql的執行時間等,功能強大。不過由于該組件使用了jquery,似乎會使用部分使用了jquery的站點無法正常工作。
    * django-db-log 將django的異常保存到數據庫。
    * django-logging 增加sql日志。直接在站點的網頁上查看當前頁面所使用sql語句以及執行時間。功能比django-debug-toolbar要弱不少,不過要是django-debug-toolbar把你的頁面毀了,那就試試這個吧。

數據庫升級

在項目開發過程中表結構的變動總是難免,django目前還不支持表結構的自動更新,不過相關的第三方app倒不少。這些app各有各的特色,具體如何選擇就要看個人的喜好了。

    * SchemaEvolution 介紹django數據庫升級的wiki頁面,相關的app都可以在這個頁面找到。

未分類

    * django-registration 注冊功能,支持帳戶的郵件激活。
    * django-tagging 為站點增加tagging功能
    * django-voting 投票功能
    * django-ajax-validation 使用ajax方式對表單進行校驗,需要jquery的支持。這個組件只能校驗,如果需要增加ajax提交表單的功能,還需要自己手動做些修改。
    * django-announcements 發送站內公告,該公告只顯示一次。可以設置公共的發送對象(所有人,指定用戶,登陸用戶)。
    * django-avatar 為用戶增加設置個人頭像的功能。支持 http://www.gravatar.com/ 和用戶上傳頭像。
    * django-dbtemplates 將django的template保存在數據庫,并通過cache來加速template的加載。這樣可以很方便的通過admin來編輯template。我想這東西應當可以用來實現一些簡單的CMS功能,不過似乎用處不是太大。
    * django-microblogging 類似Twitter的微型博客
    * django-notification 消息分發組件,用來實現類似好友最新動態的功能。
    * django-pagination 一組翻頁相關的utils,包括用于實現翻頁的tag等。
    * django-robots 通過django的admin來管理robots.txt。不過我覺得robots.txt這東西為什么還需要用admin來管理,還不如直接編輯來的方便。
    * django-messages 實現站內消息的功能。目前該組件的功能的功能還比較弱,雖然作者在進行重構,但似乎進展緩慢。如果有需要我可能會自行對該組件進行一些增強。
    * django-threadedcomments 評論組件,可以給任何的models增加評論功能。
    * django-extensions 一些全局的 management extensions。其中包括create_app的增強,使用werkzeug做開發服務器等功能。
    * django-uni-form 以div方式渲染forms
    * django-timezones 時區設置組件,允許用戶設置自己所在的時區。
    * django-bookmarks 書簽管理組件
    * django-email-confirmation 在用戶設置郵件地址后,給用戶的郵箱發送一封確認郵件。用戶點擊郵件里的link來確認郵件地址的有效性。
    * django-mailer 郵件發送的增強組件,會在郵件發送失敗時記錄失敗日志。
    * django-friends 朋友組件,支持邀請用戶成為好友等。
    * django-locations 似乎是一個基于地區的社交網絡,需要yaohoo map的支持。
    * django-oembed 方面媒體(視頻等)內容嵌入,自動將媒體的連接轉換成正確的html代碼。
    * django-swaps 易物平臺,比如用PSP換NDS啥的。
    * django-wikiapp wiki組件,支持多種wiki語法。不過目前該組件的功能還是比較簡單,比如不支持附件。
    * django-mptt 用于生成樹形列表的app。如果你認為它會自動給你生成一個完整的樹,那你就錯了,她只是一組工具。我感覺這東西并不是太好用,是否有什么優點,暫時不太清楚。
    * django-photologue 圖片管理,上傳圖片,縮略圖顯示等。
    * django-filebrowser django-admin的一個擴展,可以直接通過admin對服務器上的文件進行管理。我沒用過這東西,不過看介紹,感覺非常棒。
    * goflow Django上的一個工作流引擎,設計靈感來源于OpenFlow。沒用過這東西,對工作流也不太了解,所以也不知道這東西好不好。不過這似乎是django上唯一的一個工作流app。

seal 2009-08-21 21:54 發表評論
]]>
The flatpages app of Djangohttp://www.aygfsteel.com/sealyu/archive/2009/07/28/288799.htmlsealsealTue, 28 Jul 2009 12:28:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/07/28/288799.htmlhttp://www.aygfsteel.com/sealyu/comments/288799.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/07/28/288799.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/288799.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/288799.htmlThe flatpages app

Django comes with an optional “flatpages” application. It lets you store simple “flat” HTML content in a database and handles the management for you via Django’s admin interface and a Python API.

A flatpage is a simple object with a URL, title and content. Use it for one-off, special-case pages, such as “About” or “Privacy Policy” pages, that you want to store in a database but for which you don’t want to develop a custom Django application.

A flatpage can use a custom template or a default, systemwide flatpage template. It can be associated with one, or multiple, sites.

New in Django 1.0: Please, see the release notes

The content field may optionally be left blank if you prefer to put your content in a custom template.

Here are some examples of flatpages on Django-powered sites:

Installation

To install the flatpages app, follow these steps:

  1. Install the sites framework by adding 'django.contrib.sites' to your INSTALLED_APPS setting, if it’s not already in there.

    Also make sure you’ve correctly set SITE_ID to the ID of the site the settings file represents. This will usually be 1 (i.e. SITE_ID = 1, but if you’re not using the sites framework to manage multiple sites, it could be the ID of a different site.

  2. Add 'django.contrib.flatpages' to your INSTALLED_APPS setting.

  3. Add 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' to your MIDDLEWARE_CLASSES setting.

  4. Run the command manage.py syncdb.

How it works

manage.py syncdb creates two tables in your database: django_flatpage and django_flatpage_sites. django_flatpage is a simple lookup table that simply maps a URL to a title and bunch of text content. django_flatpage_sites associates a flatpage with a site.

The FlatpageFallbackMiddleware does all of the work. Each time any Django application raises a 404 error, this middleware checks the flatpages database for the requested URL as a last resort. Specifically, it checks for a flatpage with the given URL with a site ID that corresponds to the SITE_ID setting.

If it finds a match, it follows this algorithm:

  • If the flatpage has a custom template, it loads that template. Otherwise, it loads the template flatpages/default.html.
  • It passes that template a single context variable, flatpage, which is the flatpage object. It uses RequestContext in rendering the template.

If it doesn’t find a match, the request continues to be processed as usual.

The middleware only gets activated for 404s – not for 500s or responses of any other status code.

Note that the order of MIDDLEWARE_CLASSES matters. Generally, you can put FlatpageFallbackMiddleware at the end of the list, because it’s a last resort.

For more on middleware, read the middleware docs.

Ensure that your 404 template works

Note that the FlatpageFallbackMiddleware only steps in once another view has successfully produced a 404 response. If another view or middleware class attempts to produce a 404 but ends up raising an exception instead (such as a TemplateDoesNotExist exception if your site does not have an appropriate template to use for HTTP 404 responses), the response will become an HTTP 500 (“Internal Server Error”) and the FlatpageFallbackMiddleware will not attempt to serve a flat page.

How to add, change and delete flatpages

Via the admin interface

If you’ve activated the automatic Django admin interface, you should see a “Flatpages” section on the admin index page. Edit flatpages as you edit any other object in the system.

Via the Python API

class models.FlatPage
Flatpages are represented by a standard Django model, which lives in django/contrib/flatpages/models.py. You can access flatpage objects via the Django database API.

Flatpage templates

By default, flatpages are rendered via the template flatpages/default.html, but you can override that for a particular flatpage.

Creating the flatpages/default.html template is your responsibility; in your template directory, just create a flatpages directory containing a file default.html.

Flatpage templates are passed a single context variable, flatpage, which is the flatpage object.

Here’s a sample flatpages/default.html template:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content }}
</body>
</html>

Since you're already entering raw HTML into the admin page for a flatpage, both flatpage.title and flatpage.content are marked as not requiring automatic HTML escaping in the template.



seal 2009-07-28 20:28 發表評論
]]>
Django標簽之divisibleby(轉)http://www.aygfsteel.com/sealyu/archive/2009/05/28/278311.htmlsealsealThu, 28 May 2009 02:58:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/05/28/278311.htmlhttp://www.aygfsteel.com/sealyu/comments/278311.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/05/28/278311.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/278311.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/278311.html
Python代碼
  1. {% if value|divisibleby:"2" %}  
  2.     Even!  
  3. {% else %}  
  4.     Odd!  
  5. {% else %}  

Returns True if the value is divisible by the argument.

seal 2009-05-28 10:58 發表評論
]]>
Django中的循環http://www.aygfsteel.com/sealyu/archive/2009/05/28/278307.htmlsealsealThu, 28 May 2009 02:38:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/05/28/278307.htmlhttp://www.aygfsteel.com/sealyu/comments/278307.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/05/28/278307.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/278307.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/278307.htmlDjango不支持退出循環操作。如果我們想退出循環,可以改變正在迭代的變量,讓其僅僅包含需要迭代的項目。同理,Django也不支持continue語句,我們無法讓當前迭代操作跳回到循環頭部。(請參看本章稍后的理念和限制小節,了解下決定這個設計的背后原因)

{% for %} 標簽在循環中設置了一個特殊的 forloop 模板變量。這個變量能提供一些當前循環進展的信息:

forloop.counter 總是一個表示當前循環的執行次數的整數計數器。這個計數器是從1開始的,所以在第一次循環時 forloop.counter 將會被設置為1。例子如下:

{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

forloop.counter0 類似于 forloop.counter ,但是它是從0計數的。第一次執行循環時這個變量會被設置為0。

forloop.revcounter 是表示循環中剩余項的整型變量。在循環初次執行時 forloop.revcounter 將被設置為序列中項的總數。最后一次循環執行中,這個變量將被置1。

forloop.revcounter0 類似于 forloop.revcounter ,但它以0做為結束索引。在第一次執行循環時,該變量會被置為序列的項的個數減1。在最后一次迭代時,該變量為0。

forloop.first 是一個布爾值。在第一次執行循環時該變量為True,在下面的情形中這個變量是很有用的。

{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}

forloop.last 是一個布爾值;在最后一次執行循環時被置為True。一個常見的用法是在一系列的鏈接之間放置管道符(|)

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

The above template code might output something like this::

Link1 | Link2 | Link3 | Link4

3.

forloop.parentloop 是一個指向當前循環的上一級循環的 forloop 對象的引用(在嵌套循環的情況下)。例子在此:

{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}

forloop 變量僅僅能夠在循環中使用,在模板解析器碰到 {% endfor %} 標簽時, forloop 就不可訪問了。

Context和forloop變量

在一個 {% for %} 塊中,已存在的變量會被移除,以避免 forloop 變量被覆蓋。Django會把這個變量移動到 forloop.parentloop 中。通常我們不用擔心這個問題,但是一旦我們在模板中定義了 forloop 這個變量(當然我們反對這樣做),在 {% for %} 塊中它會在 forloop.parentloop 被重新命名。

for
輪詢數組中的每一元素。例如顯示一個給出的運動員的序列``athlete_list``:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
你同樣可以反過來用``{% for obj in list reversed %}``輪詢一個列表。
``for``循環設置了許多循環中有用的變量(見表F-1)。
Inline literal start-string without end-string.
表 F-1. {% for %}循環中的可用變量
變量名描述
forloop.counter 循環的當前重復值 (標示為1)。
forloop.counter0 循環的當前重復值 (標示為0)。
forloop.revcounter 循環到最后的重復數 (標示為1)。
forloop.revcounter0 循環到最后的重復數 (標示為0)。
forloop.first 第一次循環則為``True``。
forloop.last 最后一次循環則為``True`` 。
forloop.parentloop 用于嵌套循環,該循環位于當前循環之上。




seal 2009-05-28 10:38 發表評論
]]>
How to use Django with FastCGI, SCGI, or AJP?http://www.aygfsteel.com/sealyu/archive/2009/04/10/264942.htmlsealsealFri, 10 Apr 2009 15:39:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/04/10/264942.htmlhttp://www.aygfsteel.com/sealyu/comments/264942.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/04/10/264942.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/264942.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/264942.htmlAlthough the current preferred setup for running Django is Apache with mod_wsgi, many people use shared hosting, on which protocols such as FastCGI, SCGI or AJP are the only viable options. In some setups, these protocols may provide better performance than mod_wsgi.

Note

This document primarily focuses on FastCGI. Other protocols, such as SCGI and AJP, are also supported, through the flup Python package. See the Protocols section below for specifics about SCGI and AJP.

Essentially, FastCGI is an efficient way of letting an external application serve pages to a Web server. The Web server delegates the incoming Web requests (via a socket) to FastCGI, which executes the code and passes the response back to the Web server, which, in turn, passes it back to the client’s Web browser.

Like mod_python, FastCGI allows code to stay in memory, allowing requests to be served with no startup time. Unlike mod_python (or mod_perl), a FastCGI process doesn’t run inside the Web server process, but in a separate, persistent process.

Why run code in a separate process?

The traditional mod_* arrangements in Apache embed various scripting languages (most notably PHP, Python and Perl) inside the process space of your Web server. Although this lowers startup time – because code doesn’t have to be read off disk for every request – it comes at the cost of memory use. For mod_python, for example, every Apache process gets its own Python interpreter, which uses up a considerable amount of RAM.

Due to the nature of FastCGI, it’s even possible to have processes that run under a different user account than the Web server process. That’s a nice security benefit on shared systems, because it means you can secure your code from other users.

Prerequisite: flup

Before you can start using FastCGI with Django, you’ll need to install flup, a Python library for dealing with FastCGI. Version 0.5 or newer should work fine.

Starting your FastCGI server

FastCGI operates on a client-server model, and in most cases you’ll be starting the FastCGI process on your own. Your Web server (be it Apache, lighttpd, or otherwise) only contacts your Django-FastCGI process when the server needs a dynamic page to be loaded. Because the daemon is already running with the code in memory, it’s able to serve the response very quickly.

Note

If you’re on a shared hosting system, you’ll probably be forced to use Web server-managed FastCGI processes. See the section below on running Django with Web server-managed processes for more information.

A Web server can connect to a FastCGI server in one of two ways: It can use either a Unix domain socket (a “named pipe” on Win32 systems), or it can use a TCP socket. What you choose is a manner of preference; a TCP socket is usually easier due to permissions issues.

To start your server, first change into the directory of your project (wherever your manage.py is), and then run the runfcgi command:

./manage.py runfcgi [options]

If you specify help as the only option after runfcgi, it'll display a list of all the available options.

You'll need to specify either a socket, a protocol or both host and port. Then, when you set up your Web server, you'll just need to point it at the host/port or socket you specified when starting the FastCGI server. See the examples, below.

Protocols

Django supports all the protocols that flup does, namely fastcgi, SCGI and AJP1.3 (the Apache JServ Protocol, version 1.3). Select your preferred protocol by using the protocol=<protocol_name> option with ./manage.py runfcgi -- where <protocol_name> may be one of: fcgi (the default), scgi or ajp. For example:

./manage.py runfcgi protocol=scgi

Examples

Running a threaded server on a TCP port:

./manage.py runfcgi method=threaded host=127.0.0.1 port=3033

Running a preforked server on a Unix domain socket:

./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid

Run without daemonizing (backgrounding) the process (good for debugging):

./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock maxrequests=1

Stopping the FastCGI daemon

If you have the process running in the foreground, it's easy enough to stop it: Simply hitting Ctrl-C will stop and quit the FastCGI server. However, when you're dealing with background processes, you'll need to resort to the Unix kill command.

If you specify the pidfile option to runfcgi, you can kill the running FastCGI daemon like this:

kill `cat $PIDFILE`

...where $PIDFILE is the pidfile you specified.

To easily restart your FastCGI daemon on Unix, try this small shell script:

#!/bin/bash

# Replace these three settings.
PROJDIR="/home/user/myproject"
PIDFILE="$PROJDIR/mysite.pid"
SOCKET="$PROJDIR/mysite.sock"

cd $PROJDIR
if [ -f $PIDFILE ]; then
kill `cat -- $PIDFILE`
rm -f -- $PIDFILE
fi

exec /usr/bin/env - \
PYTHONPATH="../python:.." \
./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE

Apache setup

To use Django with Apache and FastCGI, you'll need Apache installed and configured, with mod_fastcgi installed and enabled. Consult the Apache documentation for instructions.

Once you've got that set up, point Apache at your Django FastCGI instance by editing the httpd.conf (Apache configuration) file. You'll need to do two things:

  • Use the FastCGIExternalServer directive to specify the location of your FastCGI server.
  • Use mod_rewrite to point URLs at FastCGI as appropriate.

Specifying the location of the FastCGI server

The FastCGIExternalServer directive tells Apache how to find your FastCGI server. As the FastCGIExternalServer docs explain, you can specify either a socket or a host. Here are examples of both:

# Connect to FastCGI via a socket / named pipe.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock

# Connect to FastCGI via a TCP host/port.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033

In either case, the file /home/user/public_html/mysite.fcgi doesn't actually have to exist. It's just a URL used by the Web server internally -- a hook for signifying which requests at a URL should be handled by FastCGI. (More on this in the next section.)

Using mod_rewrite to point URLs at FastCGI

The second step is telling Apache to use FastCGI for URLs that match a certain pattern. To do this, use the mod_rewrite module and rewrite URLs to mysite.fcgi (or whatever you specified in the FastCGIExternalServer directive, as explained in the previous section).

In this example, we tell Apache to use FastCGI to handle any request that doesn't represent a file on the filesystem and doesn't start with /media/. This is probably the most common case, if you're using Django's admin site:

<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>

Django will automatically use the pre-rewrite version of the URL when constructing URLs with the {% url %} template tag (and similar methods).

lighttpd setup

lighttpd is a lightweight Web server commonly used for serving static files. It supports FastCGI natively and, thus, is a good choice for serving both static and dynamic pages, if your site doesn't have any Apache-specific needs.

Make sure mod_fastcgi is in your modules list, somewhere after mod_rewrite and mod_access, but not after mod_accesslog. You'll probably want mod_alias as well, for serving admin media.

Add the following to your lighttpd config file:

server.document-root = "/home/user/public_html"
fastcgi.server = (
"/mysite.fcgi" => (
"main" => (
# Use host / port instead of socket for TCP fastcgi
# "host" => "127.0.0.1",
# "port" => 3033,
"socket" => "/home/user/mysite.sock",
"check-local" => "disable",
)
),
)
alias.url = (
"/media" => "/home/user/django/contrib/admin/media/",
)

url.rewrite-once = (
"^(/media.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/mysite.fcgi$1",
)

Running multiple Django sites on one lighttpd

lighttpd lets you use "conditional configuration" to allow configuration to be customized per host. To specify multiple FastCGI sites, just add a conditional block around your FastCGI config for each site:

# If the hostname is 'www.example1.com'...
$HTTP["host"] == "www.example1.com" {
server.document-root = "/foo/site1"
fastcgi.server = (
...
)
...
}

# If the hostname is 'www.example2.com'...
$HTTP["host"] == "www.example2.com" {
server.document-root = "/foo/site2"
fastcgi.server = (
...
)
...
}

You can also run multiple Django installations on the same site simply by specifying multiple entries in the fastcgi.server directive. Add one FastCGI host for each.

Cherokee setup

Cherokee is a very fast, flexible and easy to configure Web Server. It supports the widespread technologies nowadays: FastCGI, SCGI, PHP, CGI, SSI, TLS and SSL encrypted connections, Virtual hosts, Authentication, on the fly encoding, Load Balancing, Apache compatible log files, Data Base Balancer, Reverse HTTP Proxy and much more.

The Cherokee project provides a documentation to setting up Django with Cherokee.

Running Django on a shared-hosting provider with Apache

Many shared-hosting providers don't allow you to run your own server daemons or edit the httpd.conf file. In these cases, it's still possible to run Django using Web server-spawned processes.

Note

If you're using Web server-spawned processes, as explained in this section, there's no need for you to start the FastCGI server on your own. Apache will spawn a number of processes, scaling as it needs to.

In your Web root directory, add this to a file named .htaccess:

AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]

Then, create a small script that tells Apache how to spawn your FastCGI program. Create a file mysite.fcgi and place it in your Web directory, and be sure to make it executable:

#!/usr/bin/python
import sys, os

# Add a custom Python path.
sys.path.insert(0, "/home/user/python")

# Switch to the directory of your project. (Optional.)
# os.chdir("/home/user/myproject")

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")

Restarting the spawned server

If you change any Python code on your site, you'll need to tell FastCGI the code has changed. But there's no need to restart Apache in this case. Rather, just reupload mysite.fcgi, or edit the file, so that the timestamp on the file will change. When Apache sees the file has been updated, it will restart your Django application for you.

If you have access to a command shell on a Unix system, you can accomplish this easily by using the touch command:

touch mysite.fcgi

Serving admin media files

Regardless of the server and configuration you eventually decide to use, you will also need to give some thought to how to serve the admin media files. The advice given in the modpython documentation is also applicable in the setups detailed above.

Forcing the URL prefix to a particular value

Because many of these fastcgi-based solutions require rewriting the URL at some point inside the webserver, the path information that Django sees may not resemble the original URL that was passed in. This is a problem if the Django application is being served from under a particular prefix and you want your URLs from the {% url %} tag to look like the prefix, rather than the rewritten version, which might contain, for example, mysite.fcgi.

Django makes a good attempt to work out what the real script name prefix should be. In particular, if the webserver sets the SCRIPT_URL (specific to Apache's mod_rewrite), or REDIRECT_URL (set by a few servers, including Apache + mod_rewrite in some situations), Django will work out the original prefix automatically.

In the cases where Django cannot work out the prefix correctly and where you want the original value to be used in URLs, you can set the FORCE_SCRIPT_NAME setting in your main settings file. This sets the script name uniformly for every URL served via that settings file. Thus you'll need to use different settings files if you want different sets of URLs to have different script names in this case, but that is a rare situation.

As an example of how to use it, if your Django configuration is serving all of the URLs under '/' and you wanted to use this setting, you would set FORCE_SCRIPT_NAME = '' in your settings file.

Questions/Feedback

Having trouble? We'd like to help!

原帖地址: http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/


seal 2009-04-10 23:39 發表評論
]]>
Flex+PyAmf+Django+MySQL(轉)http://www.aygfsteel.com/sealyu/archive/2009/01/10/250804.htmlsealsealSat, 10 Jan 2009 05:51:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/01/10/250804.htmlhttp://www.aygfsteel.com/sealyu/comments/250804.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/01/10/250804.html#Feedback5http://www.aygfsteel.com/sealyu/comments/commentRss/250804.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/250804.html閱讀全文

seal 2009-01-10 13:51 發表評論
]]>
windows下Django及相關工具的安裝和配置http://www.aygfsteel.com/sealyu/archive/2009/01/09/250685.htmlsealsealFri, 09 Jan 2009 06:12:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/01/09/250685.htmlhttp://www.aygfsteel.com/sealyu/comments/250685.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/01/09/250685.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/250685.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/250685.html
網上看到很多這方面的帖子,自己也安裝了幾次,結合自己的幾次安裝過程總結一篇備用。以后隨著學習深入,逐步完善。
主要涉及到Python、PIL、Apache插件、Mysql插件、Pydev、PyAMF等幾個相關工具的安裝和配置。(假定已安裝好Apache和Mysql)

1.安裝Python
http://www.python.org上下載,(現在已經出了3.0版本了,不過跟2.x版本不兼容)點擊安裝。例如安裝到D:\Python\這個目錄。
設置環境變量:新建PYTHON_HOME,設置為 D:\Python. Path中添加;%PYTHON_HOME%;%PYTHON_HOME%\Scripts;

2.安裝PIL\Mysql的python插件\Apache的python插件
http://www.pythonware.com/products/pil/ 下載PIL的安裝文件
http://sourceforge.net/projects/mysql-python 下載mysql-python
http://httpd.apache.org/modules/python-download.cgi 下載mod-python

PIL是Python Imaging Library縮寫,主要用來處理圖片用的,這里安裝它是為了在Django系統中用它來對上傳的圖片自動的生成縮略圖的。安裝方法也相當的簡單,直接雙擊運行安裝文件,然后一路next即可。

mysql-python是Mysql的python插件,直接運行安裝。
這兩個都將安裝在%PYTHON_HOME%\Lib\site-packages下面。

mod-python是Apache的python插件,如果你選擇使用Apache作為服務器,將需要安裝此文件,
在下載mod_python的時候要注意與apache版本的匹配,安裝過程需要你選擇apache的安裝目錄。
詳細的配置可以看這個:Django在使用mod_python+apache中配置VirtualHost 或者 Apache + mod_python + Django Step by Step

3.安裝Django
http://www.djangoproject.com/ 下載django安裝文件。
(現在是1.0.2版本,我曾試圖用python2.6上安裝django1.0,提示不匹配。所以現在我還在使用python2.5.)
將安裝文件解壓到一個目錄,例如 D:\Django , 打開cmd,cd進這個目錄
執行 python setup.py install 將會把Django安裝到%PYTHON_HOME%\Lib\site-packages下面并同時設置好sys.path。
設置環境變量,將%PYTHON_HOME\Libsite-packages\django添加到path中。

4.安裝Pydev(Python的eclipse插件)
http://sourceforge.net/projects/pydev/ 下載安裝文件

下載后解壓,將plugins目錄下所有文件挪到Eclipse的相應目錄下,將feature目錄下所有文件挪到Eclipse的相應目錄下,最后啟動 Eclipse,在Help-》Software Upates-》Manage Configuration,然后彈出的界面即可看到pydev的插件。

另一種安裝插件的方法是:Help-》Software Upates-》Find and Install-》Search for new features to install-》New remote site-》隨便起個name如pydev,url填 http://pydev.sf.net/updates/ -》然后照著提示下載安裝即可。

配置Pydev:

在Eclipse IDE 下, 打開 Window->Preferences 對話框,從右側的樹形列表中選擇“ PyDev”->“Interpreter Python”, 點擊New按鈕,從Python的安裝路徑下選擇Python.exe,然后會彈出一個對話框讓你勾選System PYTHONPATH。最后點Ok,退出。






seal 2009-01-09 14:12 發表評論
]]>
Python 絕對簡明手冊(轉自-啄木鳥社區)http://www.aygfsteel.com/sealyu/archive/2008/12/29/248902.htmlsealsealMon, 29 Dec 2008 06:50:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/12/29/248902.htmlhttp://www.aygfsteel.com/sealyu/comments/248902.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/12/29/248902.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/248902.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/248902.html閱讀全文

seal 2008-12-29 14:50 發表評論
]]>
PIL 中使用JPEG圖片http://www.aygfsteel.com/sealyu/archive/2008/12/11/245799.htmlsealsealThu, 11 Dec 2008 14:26:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/12/11/245799.htmlhttp://www.aygfsteel.com/sealyu/comments/245799.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/12/11/245799.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/245799.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/245799.html 還需安裝jpeg庫文件,可到http://www.ijg.org下載。
安裝jpeg庫,輸入以下命令進行安裝:
tar xfz jpegsrc.v6b.tar.gz
cd jpeg-6b
./configure
make
make test
make install
make install-lib




seal 2008-12-11 22:26 發表評論
]]>
How to use Django with Apache and mod_pythonhttp://www.aygfsteel.com/sealyu/archive/2008/11/07/239347.htmlsealsealFri, 07 Nov 2008 15:44:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/07/239347.htmlhttp://www.aygfsteel.com/sealyu/comments/239347.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/07/239347.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239347.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239347.htmlApache with mod_python currently is the preferred setup for using Django on a production server.

mod_python is similar to (and inspired by) mod_perl : It embeds Python within Apache and loads Python code into memory when the server starts. Code stays in memory throughout the life of an Apache process, which leads to significant performance gains over other server arrangements.

Django requires Apache 2.x and mod_python 3.x, and you should use Apache’s prefork MPM, as opposed to the worker MPM.

You may also be interested in How to use Django with FastCGI, SCGI or AJP (which also covers SCGI and AJP).

Basic configuration

To configure Django with mod_python, first make sure you have Apache installed, with the mod_python module activated.

Then edit your httpd.conf file and add the following:

<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
</Location>

...and replace mysite.settings with the Python import path to your Django project's settings file.

This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the Django mod_python handler." It passes the value of DJANGO_SETTINGS_MODULE so mod_python knows which settings to use.

New in Django 1.0: The PythonOption django.root ... is new in this version.

Because mod_python does not know we are serving this site from underneath the /mysite/ prefix, this value needs to be passed through to the mod_python handler in Django, via the PythonOption django.root ... line. The value set on that line (the last item) should match the string given in the <Location ...> directive. The effect of this is that Django will automatically strip the /mysite string from the front of any URLs before matching them against your URLConf patterns. If you later move your site to live under /mysite2, you will not have to change anything except the django.root option in the config file.

When using django.root you should make sure that what's left, after the prefix has been removed, begins with a slash. Your URLConf patterns that are expecting an initial slash will then work correctly. In the above example, since we want to send things like /mysite/admin/ to /admin/, we need to remove the string /mysite from the beginning, so that is the django.root value. It would be an error to use /mysite/ (with a trailing slash) in this case.

Note that we're using the <Location> directive, not the <Directory> directive. The latter is used for pointing at places on your filesystem, whereas <Location> points at places in the URL structure of a Web site. <Directory> would be meaningless here.

Also, if your Django project is not on the default PYTHONPATH for your computer, you'll have to tell mod_python where your project can be found:

<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
PythonPath "['/path/to/project'] + sys.path"
</Location>

The value you use for PythonPath should include the parent directories of all the modules you are going to import in your application. It should also include the parent directory of the DJANGO_SETTINGS_MODULE location. This is exactly the same situation as setting the Python path for interactive usage. Whenever you try to import something, Python will run through all the directories in sys.path in turn, from first to last, and try to import from each directory until one succeeds.

An example might make this clearer. Suppose you have some applications under /usr/local/django-apps/ (for example, /usr/local/django-apps/weblog/ and so forth), your settings file is at /var/www/mysite/settings.py and you have specified DJANGO_SETTINGS_MODULE as in the above example. In this case, you would need to write your PythonPath directive as:

PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"

With this path, import weblog and import mysite.settings will both work. If you had import blogroll in your code somewhere and blogroll lived under the weblog/ directory, you would also need to add /usr/local/django-apps/weblog/ to your PythonPath. Remember: the parent directories of anything you import directly must be on the Python path.

Note

If you're using Windows, we still recommended that you use forward slashes in the pathnames, even though Windows normally uses the backslash character as its native separator. Apache knows how to convert from the forward slash format to the native format, so this approach is portable and easier to read. (It avoids tricky problems with having to double-escape backslashes.)

This is valid even on a Windows system:

PythonPath "['c:/path/to/project'] + sys.path"

You can also add directives such as PythonAutoReload Off for performance. See the mod_python documentation for a full list of options.

Note that you should set PythonDebug Off on a production server. If you leave PythonDebug On, your users would see ugly (and revealing) Python tracebacks if something goes wrong within mod_python.

Restart Apache, and any request to /mysite/ or below will be served by Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed the full URL.

When deploying Django sites on mod_python, you'll need to restart Apache each time you make changes to your Python code.

Multiple Django installations on the same Apache

It's entirely possible to run multiple Django installations on the same Apache instance. Just use VirtualHost for that, like so:

NameVirtualHost *

<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>

<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>

If you need to put two Django installations within the same VirtualHost (or in different VirtualHost blocks that share the same server name), you'll need to take a special precaution to ensure mod_python's cache doesn't mess things up. Use the PythonInterpreter directive to give different <Location> directives separate interpreters:

<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
</Location>

<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter othersite
</Location>
</VirtualHost>

The values of PythonInterpreter don't really matter, as long as they're different between the two Location blocks.

Running a development server with mod_python

If you use mod_python for your development server, you can avoid the hassle of having to restart the server each time you make code changes. Just set MaxRequestsPerChild 1 in your httpd.conf file to force Apache to reload everything for each request. But don't do that on a production server, or we'll revoke your Django privileges.

If you're the type of programmer who debugs using scattered print statements, note that print statements have no effect in mod_python; they don't appear in the Apache log, as one might expect. If you have the need to print debugging information in a mod_python setup, either do this:

assert False, the_value_i_want_to_see

Or add the debugging information to the template of your page.

Serving media files

Django doesn't serve media files itself; it leaves that job to whichever Web server you choose.

We recommend using a separate Web server -- i.e., one that's not also running Django -- for serving media. Here are some good choices:

If, however, you have no option but to serve media files on the same Apache VirtualHost as Django, here's how you can turn off mod_python for a particular part of the site:

<Location "/media">
SetHandler None
</Location>

Just change Location to the root URL of your media files. You can also use <LocationMatch> to match a regular expression.

This example sets up Django at the site root but explicitly disables Django for the media subdirectory and any URL that ends with .jpg, .gif or .png:

<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>

<Location "/media">
SetHandler None
</Location>

<LocationMatch "".(jpg|gif|png)$">
SetHandler None
</LocationMatch>

Serving the admin files

Note that the Django development server automagically serves admin media files, but this is not the case when you use any other server arrangement. You're responsible for setting up Apache, or whichever media server you're using, to serve the admin files.

The admin files live in (django/contrib/admin/media) of the Django distribution.

Here are two recommended approaches:

  1. Create a symbolic link to the admin media files from within your document root. This way, all of your Django-related files -- code and templates -- stay in one place, and you'll still be able to svn update your code to get the latest admin templates, if they change.
  2. Or, copy the admin media files so that they live within your Apache document root.

Using "eggs" with mod_python

If you installed Django from a Python egg or are using eggs in your Django project, some extra configuration is required. Create an extra file in your project (or somewhere else) that contains something like the following:

import os
os.environ['PYTHON_EGG_CACHE'] = '/some/directory'

Here, /some/directory is a directory that the Apache webserver process can write to. It will be used as the location for any unpacking of code the eggs need to do.

Then you have to tell mod_python to import this file before doing anything else. This is done using the PythonImport directive to mod_python. You need to ensure that you have specified the PythonInterpreter directive to mod_python as described above (you need to do this even if you aren't serving multiple installations in this case). Then add the PythonImport line in the main server configuration (i.e., outside the Location or VirtualHost sections). For example:

PythonInterpreter my_django
PythonImport /path/to/my/project/file.py my_django

Note that you can use an absolute path here (or a normal dotted import path), as described in the mod_python manual. We use an absolute path in the above example because if any Python path modifications are required to access your project, they will not have been done at the time the PythonImport line is processed.

Error handling

When you use Apache/mod_python, errors will be caught by Django -- in other words, they won't propagate to the Apache level and won't appear in the Apache error_log.

The exception for this is if something is really wonky in your Django setup. In that case, you'll see an "Internal Server Error" page in your browser and the full Python traceback in your Apache error_log file. The error_log traceback is spread over multiple lines. (Yes, this is ugly and rather hard to read, but it's how mod_python does things.)

If you get a segmentation fault

If Apache causes a segmentation fault, there are two probable causes, neither of which has to do with Django itself.

  1. It may be because your Python code is importing the "pyexpat" module, which may conflict with the version embedded in Apache. For full information, see Expat Causing Apache Crash.
  2. It may be because you're running mod_python and mod_php in the same Apache instance, with MySQL as your database backend. In some cases, this causes a known mod_python issue due to version conflicts in PHP and the Python MySQL backend. There's full information in the mod_python FAQ entry.

If you continue to have problems setting up mod_python, a good thing to do is get a barebones mod_python site working, without the Django framework. This is an easy way to isolate mod_python-specific problems. Getting mod_python Working details this procedure.

The next step should be to edit your test code and add an import of any Django-specific code you're using -- your views, your models, your URLconf, your RSS configuration, etc. Put these imports in your test handler function and access your test URL in a browser. If this causes a crash, you've confirmed it's the importing of Django code that causes the problem. Gradually reduce the set of imports until it stops crashing, so as to find the specific module that causes the problem. Drop down further into modules and look into their imports, as necessary.



seal 2008-11-07 23:44 發表評論
]]>
在RedHat AS4 上安裝Mysql_python模塊時遇到的問題http://www.aygfsteel.com/sealyu/archive/2008/11/07/239288.htmlsealsealFri, 07 Nov 2008 09:03:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/07/239288.htmlhttp://www.aygfsteel.com/sealyu/comments/239288.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/07/239288.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239288.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239288.html
在RedHat AS4 上配置Apache+MySQL+Django 環境時,首先安裝好了Apache和Python以及Django和Mysql,
其中Mysql是編譯安裝的5.0版本。
下載了MySQL-python-1.2.2.tar.gz之后,解壓縮,cd進去,
執行: python setup.py build時報錯:
File "/tmp/easy_install-nHSsgl/MySQL-python-1.2.2/setup_posix.py", line 26, in mysql_config
EnvironmentError: mysql_config not found

后來發現是由于Mysql編譯安裝后沒有 mysql_config這個值,解決方法:
打開 setup_posix.py, 將其中line:26手動改成系統中對應的Mysql選項(這里我的是/usr/local/mysql):
mysql_config = /usr/local/mysql/bin/mysql_config

重新執行 :python setup.py build,沒有了剛才的錯誤,但是出現了另外一個錯誤:
error: /usr/bin/ld: cannot find -lmysqlclient

網上搜索了一下這個錯誤,發現有幾種不同的情況,主要有以下幾個原因:
1.沒有安裝mysqlclient。解決方法:找到對應的版本進行安裝。
2.安裝的mysqlclient的版本不匹配。對應鏈接: http://www.hao32.com/webserver/258.html
3.已經安裝了對應的mysqlclient但是找不到對應的鏈接。這是在一個國外的網站上看到的,具體網址已經找不到了,后來那位仁兄將對應的
mysql_home/lib/mysql文件夾下面libmysqlclient對應的文件全部拷貝到/usr/local/lib下面才解決了問題。

按照對應方案,問題解決。
重新執行:
python setup.py build
python setup.py install
安裝完成。




seal 2008-11-07 17:03 發表評論
]]>
在linux上配置Django+LIghthttpd + fastcgihttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239127.htmlsealsealThu, 06 Nov 2008 14:36:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239127.htmlhttp://www.aygfsteel.com/sealyu/comments/239127.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239127.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239127.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239127.htmlIn today’s world, web development is all about turnaround. Businesses want to maximize production outcome while minimizing development and production time. Small, lean development teams are increasingly becoming the normal large development departments. Enter Django: a popular Python web framework that invokes the RWAD (rapid web application development) and DRY (don’t repeat yourself) principles with clean, pragmatic design.

This article is not about teaching you how to program in Python, nor how to use the Django framework. It’s about showing how to promote your Django applications onto an existing Apache or Lighttpd environment.

We will conclude with a simple way that you can improve the performance of your Django application by using caching to speed up access time. This article also assumes that you are running Fedora as your web application server, but all the packages mentioned in this article are also available under the Extra Packages for Enterprise Linux repository , which means these instructions should also be valid under Red Hat Enterprise Linux or CentOS servers.

What you need

You must have Django installed:

# yum install Django

If you want to serve Django apps under Apache:

# yum install httpd
# yum install mod_python

If you want to serve Django apps under Lighttpd:

# yum install lighttpd
# yum install lighttpd-fastcgi
# yum install python-flup

Installing memcached to ’speed up’ Django apps:

# yum install memcached
# yum install python-memcached

Starting a new Django project

1. Create a development workspace.

$ mkdir -p $LOCATION_TO_YOUR_DEV_AREA
$ cd $LOCATION_TO_YOUR_DEV_AREA

2. Start a new base Django project. This creates the boiler plate project structure.

$ django-admin.py startproject my_app

3. Start the Django development web server on port 8080 (or whatever other port you’d like).

Note: The development web server is just for testing and verification. Do not use it as a production application server!

$ python manage.py runserver 8080

4. Run your Django project under Apache with mod_python by enabling mod_python on httpd.conf (/etc/httpd/conf/httpd.conf).

After installing mod_python, a file called python.conf should already be placed in /etc/httpd/conf.d/, which enables mod_python on your system.

5. Create virtual hosts by creating a new file at /etc/httpd/conf.d/myapp.conf.

 

DocumentRoot /var/www/html/
ServerName your_domain_name
ErrorLog logs/my_app-error.log
CustomLog logs/my_app-access_log common


SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE my_app.settings
PythonDebug On
PythonPath “[’/var/www/django/’] + sys.path”


Running your Django project under Lighthttpd with fastcgi

The first thing you must do is start up your FastCGI server.

./manage.py runfcgi method=prefork socket=/var/www/myapp.sock pidfile=django_myapp.pid

Then modify your lighttpd.conf file to use the FastCGI server.

server.document-root = "/var/www/django/"
fastcgi.server = (
"/my_app.fcgi" => (
"main" => (
# Use host / port instead of socket for TCP fastcgi
# "host" => "127.0.0.1",
# "port" => 3033,
"socket" => "/var/www/my_app.sock",
"check-local" => "disable",
)
),
)
alias.url = (
"/media/" => "/var/www/django/media/",
)

url.rewrite-once = (
"^(/media.*)$" => "$1",
"^/favicon.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/my_app.fcgi$1",
)

Setting up caching in Django

Django has many different caching backends, including database, memory, filesystem, and the ever popular memcached. According to http://www.danga.com/memcached/, memcached is “a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.” It’s used by high traffic sites such as Slashdot and Wikipedia. This makes it a prime candidate for caching in your cool new web app.

First, verify that memcached is running using the memcached’s init script.

$ /etc/init.d/memcached status
memcached (pid 6771) is running...

If it’s not running, you can manually start it.

$ /sbin/service memcached start

If you want to make sure it will automatically start every time after a reboot:

$ /sbin/chkconfig --level 35 memcached on 

Now that you have verified that memcached is running, you will want to tell your Django application to use memcached as it’s caching backend. You can do this by adding a CACHE_BACKEND entry to your settings.py file.

CACHE_BACKEND = 'memcached://127.0.0.1:11211/'

The format is “backend://host:port/” or “backend:///path” depending on the backend chosen. Since we are using memcached, we have the option to run multiple daemons on different servers and share the cache across multiple machines. If you want to do this all you must do is add in the servers:port combinations in the CACHE_BACKEND and separate them by semicolons. In this example we share the cache across three different memcached servers:

CACHE_BACKEND = 'memcached://127.0.0.1:11211;192.168.0.10:11211;192.168.0.11/'

For more information on the different types of caching that can be performed in the Django framework, please refer to their official documentation.



seal 2008-11-06 22:36 發表評論
]]>
Django在使用mod_python+apache中配置VirtualHosthttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239122.htmlsealsealThu, 06 Nov 2008 14:13:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239122.htmlhttp://www.aygfsteel.com/sealyu/comments/239122.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239122.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239122.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239122.htmlWith Django 0.95 being introduced being introduced a few days ago, I figured a quick post on what we experienced installing Django might help someone out. None of this covers new ground, but perhaps another telling of the story will provide someone an extra hook to grab onto.

This tutorial is going to cover installing Django with the following:

  • Apache 2
  • MySQL
  • mod_python
  • Python (2.4)

For the record, I'm running all of this off of OpenSuSE 10.1 - so obligatory YMMV. Please comment with suggestions or problems if so, though.

First off, make sure you've got Apache up and running. ps aux | grep httpd can tell ya for the most part. If you don't know how to do this much, though, I'm afraid you're reading the wrong tutorial.

Step 1: Install mod_python

This will vary pretty widely amongst distributions, but our goal was to have a package manager do it. One of the below will probably work for you:

  • SuSE: In YaST, search for mod_python in Software Management
  • Ubuntu/Debian/apt-based: apt-get install libapache2-mod-python2.4
  • Redhat/FC4: yum install mod_python

Step 2: Install Django

So with mod_python installed, now we can get to Django. We have been tracking along with Subversion up until now, but since we're getting ready to put a large (for us) site into production, we are planning on sticking with numbered releases, but it remains to be seen if we'll change our minds on that one in order to take advantage of the enhancements that continue to stream in. If you want to live closer to the edge, you can get the development trunk through subversion.

# Most recent version at this point in time is 0.95
wget http://www.djangoproject.com/download/0.95/tarball/
tar -xzvf Django-0.95.tar.gz
cd Django-0.95
python setup.py install

Note that the last command will automatically download and install 'setuptools' if you don't already have it installed.

Step 3: Create a Project

So assuming everything went well, (It did, didn't it?), we're ready to start our first django project. Start your first project by going into the directory you want to hold your django projects (preferably outside of your web document root), and typing:

django-admin.py startproject myProject

As the djangoproject.com tutorial says…

django-admin.py should be on your system path if you installed Django via python setup.py. If it's not on your path, you can find it in site-packages/django/bin, where site-packages is a directory within your Python installation. Consider symlinking to django-admin.py from some place on your path, such as /usr/local/bin.

This will start you off with the basic settings and files needed for your django project. But we're not done quite yet! We have to tell apache what to do to handle mod_python requests.

Step 4: Configure Apache

To get apache to handle python requests, we first need to activate mod_python. Again, this is one of those things that will vary pretty widely through distributions, but essentially you'll need this command in Apache's httpd.conf file:

LoadModule python_module modules/mod_python.so

(note: Purportedly on debian this is done for you automatically - so you will likely be able to skip this step)
In OpenSuSE the best way to do this is to go into YaST-> Sysconfig Editor-> Network-> WWW-> Apache2, and append 'python' onto the APACHE_MODULES setting. There may be other ways to do this more painlessly than file editing in other distro's, as well. Let me know if there are and I will update this section.

Now that apache knows about python, we have to tell it where to -use- python. So go into your httpd.conf file (if you're using virtual hosts, pick the appropriate virtual host config file) and add this location directive:

<location "/myProject">
     SetHandler python-program
     PythonHandler django.core.handlers.modpython
     SetEnv DJANGO_SETTINGS_MODULE myProject.settings
     PythonPath "['/path/to/your/django/projects'] + sys.path"
     PythonDebug On
     PythonInterpreter myProject
 </location>

Now save, restart apache, and browse to your server + /myProject (i.e., http://www.yourhost.com/myProject).

Did it come up with a special looking 404 error? If so, you've got Django installed, man! Better go follow the more informative and better written Django Tutorial to see how to really get rolling with it - you're ready to start developing!



seal 2008-11-06 22:13 發表評論
]]>
Apache + mod_python + Django Step by Stephttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239110.htmlsealsealThu, 06 Nov 2008 12:57:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239110.htmlhttp://www.aygfsteel.com/sealyu/comments/239110.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239110.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239110.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239110.html

1、下載需要模塊。

a、apache (httpd-2.0.54.tar.gz or later)
b、mod_python (mod_python-3.3.1.tgz)
c、Django (Django-0.96.tar.gz)

默認已安裝 Python (http://www.python.org)

2、安裝配置環境。

首先,正常安裝 apache 和 mod_python (http://www.modpython.org/),注意要打開 apache 的 DSO 功能,執行:

#...
#tar -zxvf httpd-2.0.54.tar.gz
#cd httpd-2.0.54
#./configure --prefix=/usr/local/apache2 --enable-so --enable-mods-shared=all
#make install clean
#...
#tar -zxvf mod_python-3.3.1.tgz
#cd mod_python-3.3.1
#./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/local/bin/python
#make install clean
#...
#tar -zxvf Django-0.96.tar.gz
#cd Django-0.96
#python setup.py install (If you installed Django using setup.py install, uninstalling is as simple as deleting the django directory from your Python site-packages.)
#...

這 樣我們就安裝好 Apache + mod_python + Django 了,你可以執行 apachectl start 測試一下能不能成功。然后我們開始配置環境,首先配置 httpd.conf 加入 LoadModule python_module modules/mod_python.so (在安裝 mod_python 的時候安裝程序會自動把 mod_python.so 拷貝到 apache 的 modules 目錄下),接著配置虛擬主機。

到這里你就可以利用 mod_python 來進行編程了,然后我們來配置一下 Django 并通過一個實例來讓大家對這個現今最 HOT 的 python web 框架有一個大體的了解:首先,我們來學習一下用 django-admin.py 工具來簡化你的工作 (當我們安裝 Django 的時候,安裝程序會自動把 django-admin.py 拷貝到 系統 PATH 下,所以我們可以直接使用它)。首先進入到我們的 python 程序目錄 (我用的是:{DOCUMENT_ROOT}/python),執行:

#django-admin.py startproject newtest

這樣就可以生成我們的測試工程了默認情況下會生成 {DOCUMENT_ROOT}/python/newtest 目錄,該目錄下會有如下文件:

__init__.py (表示這是一個 Python 的包)
manage.py (提供簡單化的 django-admin.py 命令,特別是可以自動進行 DJANGO_SETTINGS_MODULES 和 PYTHONPATH 的處理,而沒有這個命令,處理上面環境變量是件麻煩的事情)
settings.py (它是django的配置文件)
uls.py (url映射處理文件, Karrigell 沒有這種機制,它通過目錄/文件/方法來自動對應,而 Django 的url映射是url對于某個模塊方法的映射,目前不能自動完成)

然后我們在 apache 的虛擬主機配置文件里面加上:

<Location "/newtest/">
SetHandler python-program
PythonPath "sys.path+['{DOCUMENT_ROOT}/python']"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE newtest.settings
#PythonInterpreter mysite
PythonDebug On
</Location>

這 里要注意的是對于 PythonPath,必須設置成工程目錄 ({DOCUMENT_ROOT}/python/newtest) 的上一級目錄!這樣我們就完成了 Django 和 apache 的整合了,趕快試一下吧,我們寫一個 action 來測試一下 Django 的功能:

3、編寫測試程序。

1> 首先,創建 ./list.py :

#coding=utf-8
from django.shortcuts import render_to_response

address = [
{'name':'張三', 'address':'地址一'},
{'name':'李四', 'address':'地址二'}
]

def index(request):
return render_to_response('list.html', {'address': address})

2> 然后,創建一個模版文件 ./templates/list.html :

<h2>通訊錄</h2>
<table border="1">
<tr><th>姓名</th><th>地址</th></tr>
{% for user in address %}
<tr>
<td>{{ user.name }}</td>
<td>{{ user.address }}</td>
</tr>
{% endfor %}
</table>

3> 設置模版目錄 (編輯 ./settings.py) :

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates".
# Always use forward slashes, even on Windows.
'./templates',
)

4> 修改 urls.py :

from django.conf.urls.defaults import *

urlpatterns = patterns('',
# Example:
# (r'^newtest/', include('newtest.foo.urls')),
(r'^newtest/list/$', 'newtest.list.index'),

# Uncomment this for admin:
# (r'^admin/', include('django.contrib.admin.urls')),
)

5> 重啟 Apache 并訪問相應 url (http://localhost/newtest/list/) 即可看到結果頁面了:

通訊錄
姓名 地址
張三 地址一
李四 地址二

到這里,你已經掌握了 Django 框架的基本內容了,就可以進一步學習 Django 的其他內容了,Enjoy It :)



seal 2008-11-06 20:57 發表評論
]]>
Redhat AS5 + Apache2 + Django 1.0 配置 (轉)http://www.aygfsteel.com/sealyu/archive/2008/11/06/239046.htmlsealsealThu, 06 Nov 2008 07:59:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239046.htmlhttp://www.aygfsteel.com/sealyu/comments/239046.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/06/239046.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/239046.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/239046.html1. 安裝 apach2 服務器。
這個很簡單,從官網上下載源代碼,httpd-2.2.9.tar.gz,解壓縮后 configure , make ,make install. 會安裝在/usr/local/目錄下。
使用命令/usr/local/apache2/bin/apachectl start     開啟apache服務。
使用命令/usr/local/apache2/bin/apachectl stop     停止apache服務。
使用命令/usr/local/apache2/bin/apachectl restart 重新啟動apache服務。

2. 安裝python 2.5
從官網上下載2.5版本,Python-2.5.2.tgz,解壓縮后./configure, make , make install.就可以完成安裝。默認安裝目錄為/usr/local/lib/python2.5/
3. 安裝mod_python.
./configure –with-apxs=/usr/local/apache2/bin/apxs –with-python=/usr/bin/python2.5,再make, make install 即可。安裝完畢后會在目錄/usr/local/apache2/modules下有文件mod_python.so,這個在后面要使用到。
4. 安裝django 1.0
官網下 載1.0版本Django-1.0.tar.gz,解壓縮,使用命令python setup.py install 安裝,注意,如果機器里有以前的版本,一定要把以前的版本文件完全卸載活刪除,django 不會覆蓋以前的文件。默認安裝目錄為/usr/local/lib/python2.5/site-packages/django/
5.安裝sqlite
這里使用到的數據庫為sqlite3,所以要安裝相應的包,這里 從官網下載pysqlite-2.3.5.tar.gz,安裝很容易。
6.配置文件.
這里使用了最簡單的配置方法,直接修改/usr/local/apache2/conf/httpd.conf
(1) ,默認端口,80,可以不修改。
(2) 在有LoadModule example字樣的下面添加一下一行
LoadModule python_module modules/mod_python.so
(3) 配置ServerName,在有 #ServerName www.example.com:80字樣的下面添加一下行:
ServerName yourIP:80
(4) 這是最重要的一步了。在有字樣# This should be changed to whatever you set DocumentRoot to.的后面,修改<Directory> … </Directory>中間的內容為:

<Directory “/home/af/af“>
#
# Possible values for the Options directive are “None”, “All”,
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that “MultiViews” must be named *explicitly* — “Options All”
# doesn’t give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
#Options Indexes FollowSymLinks
#PythonHandler django.core.handlers.modpython
PythonPath “['/home/af/af','/usr/local/lib/python2.5/site-packages'] + sys.path”
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE aftest.settings
SetHandler python-program
PythonDebug On

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be “All”, “None”, or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
#AllowOverride None

#
# Controls who can get stuff from this server.
#
#Order allow,deny
Allow from all

</Directory>

其中藍色部分為要修改和添加的部分,/home/af/af是Django 工程所在的目錄,aftest為項目名稱。
(5)添加media。這里以安裝Django自己提供的admin為例。
在上一步的</Directory>下面再添加
Alias /media /usr/local/lib/python2.5/site-packages/django/contrib/admin/media
<Location “/media”>
Options None
SetHandler None
Allow from all
</Location>

即可。

配置完畢。



seal 2008-11-06 15:59 發表評論
]]>
Using PIL with Djangohttp://www.aygfsteel.com/sealyu/archive/2008/11/06/238957.htmlsealsealThu, 06 Nov 2008 01:32:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/11/06/238957.htmlhttp://www.aygfsteel.com/sealyu/comments/238957.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/11/06/238957.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/238957.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/238957.htmlHere’s a simple django view which creates a PIL image on the fly, and returns it as a PNG image:

from django.utils.httpwrappers import HttpResponse
from PIL import Image

import random
INK = "red", "blue", "green", "yellow"

def image(request):

# ... create/load image here ...
image = Image.new("RGB", (800, 600), random.choice(INK))

# serialize to HTTP response
response = HttpResponse(mimetype="image/png")
image.save(response, "PNG")
return response
 

To draw things on the fly, you can use either PIL’s ImageDraw module, or the aggdraw module:

from django.utils.httpwrappers import HttpResponse
from PIL import Image
from aggdraw import Draw, Pen, Brush, Font

import random

def graphics(request):

image = Image.new("RGB", (800, 600), "white")
draw = Draw(image)

# ... draw graphics here ...
for i in range(20):
x0 = random.randint(0, image.size[0])
y0 = random.randint(0, image.size[1])
x1 = random.randint(0, image.size[0])
y1 = random.randint(0, image.size[1])
draw.rectangle((x0, y0, x1, y1), Pen(random.choice(INK), 5))

draw.flush()

response = HttpResponse(mimetype="image/png")
image.save(response, "PNG")
return response


seal 2008-11-06 09:32 發表評論
]]>
主站蜘蛛池模板: 桦甸市| 靖边县| 祁阳县| 滨州市| 中江县| 桐乡市| 衢州市| 浪卡子县| 合山市| 吴旗县| 濉溪县| 水富县| 高雄市| 郑州市| 宜宾市| 蒙山县| 都兰县| 包头市| 辽源市| 翼城县| 永年县| 武安市| 东丽区| 台中市| 内乡县| 额济纳旗| 上蔡县| 东乡| 五华县| 呼伦贝尔市| 新密市| 漾濞| 项城市| 达拉特旗| 定结县| 巴林右旗| 商都县| 普宁市| 长子县| 永春县| 墨脱县|