<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>年华转瞬 &#187; django-orm</title>
	<atom:link href="http://blog.xiaket.org/tag/django-orm/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xiaket.org</link>
	<description>xiaket 的网志</description>
	<lastBuildDate>Sat, 21 Aug 2010 02:31:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>一天idea散记</title>
		<link>http://blog.xiaket.org/2009/12/31/todays-ideas/</link>
		<comments>http://blog.xiaket.org/2009/12/31/todays-ideas/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 17:04:56 +0000</pubDate>
		<dc:creator>xiaket</dc:creator>
				<category><![CDATA[Django开发]]></category>
		<category><![CDATA[Python开发]]></category>
		<category><![CDATA[其它]]></category>
		<category><![CDATA[django-admin]]></category>
		<category><![CDATA[django-orm]]></category>

		<guid isPermaLink="false">http://blog.xiaket.org/?p=226</guid>
		<description><![CDATA[Django相关

问: 一个models.py文件里面定义了一群模型(不知道多少个), 我想要得到一个字典, 键为模型名, 值为模型的类.

答: 这是个比较丑的办法, 暂时想不到更漂亮的了:

<span class="readmore"><a href="http://blog.xiaket.org/2009/12/31/todays-ideas/" title="一天idea散记">阅读全文——共1549字</a></span>]]></description>
			<content:encoded><![CDATA[<h3>Django相关</h3>
<p>问: 一个models.py文件里面定义了一群模型(不知道多少个), 我想要得到一个字典, 键为模型名, 值为模型的类.</p>
<p>答: 这是个比较丑的办法, 暂时想不到更漂亮的了:</p>
<pre class="brush: python;">
from django.db import models
import msgcenter.models
class_dict = {}
for name in dir(msgcenter.models):
    try:
        status = eval(&quot;issubclass(msgcenter.models.%s, models.Model)&quot; % name)
        class_dict[name] = eval(&quot;msgcenter.models.%s&quot; % name)
    except:
        pass
</pre>
<p>问: 一个模型里面有很多的field, 怎么拿到这个field的列表?</p>
<p>答: 这个是一个内置的属性:</p>
<pre class="brush: python;">
&gt;&gt;&gt; from msgcenter.models import Project
&gt;&gt;&gt; Project._meta.object_name
'Project'
&gt;&gt;&gt; Project._meta.get_all_field_names()
['admins',
 'fullname',
 'id',
 'popo_acount',
 'shortname']
</pre>
<p>不过这个似乎还包含了一些外键之类的东西, 有时间再细细研究下.</p>
<p>问: 我定义了一个模型, 里面有个field用来记录作者的ip, 普通视图函数还好说, 但是怎么样能够在admin界面下也能正确保存这个ip信息呢?</p>
<p>答: 几种办法. 最丑的: 改urls.py, 让我们匹配的规则在admin的规则的前面, 然后自己写视图函数, 外观做得很像很像admin界面&#8230;. 最剑走偏锋的: 用中间件, 对于到某个特殊的url的POST, 将POST的内容改掉, 添加用户的ip. 最正统的: 改admin.py里面的save_model方法&#8230;</p>
<p>第二种方法是今天和LD讨论出来的, 很有意思, 中间件这样用虽然很非主流, 但也不失为一个极端情况下的投机取巧之道. 用中间件你可以任意地修改request/response对象, 一切尽在掌握~</p>
<h3>工作相关</h3>
<p>遇到一个诡异的问题, 某个服务用户的crontab里运行的脚本ls输出和通过sudo来以这个服务用户的身份运行ls的输出结果不一样, 时间格式不同, 后来强制指定&#8211;time-style搞定&#8230;</p>
<p>今天开始写脚本处理<a href="http://mirrors.163.com/">开源镜像服务器</a>上Web服务器的日志. 今天主要解决的问题是一个很大的日志文件如何得到每个小时的访问次数. grep -c肯定是可以的, 但是效率很差. 目前想到的方法是利用日志里面的时间戳, 在python里用file对象的seek方法来处理, 而不是逐行处理, 不过这样效率到底能提高多少, 目前脚本没写出来我还没底, 目标是一个2G的文件一秒能搞定, 这样比逐行处理效率要高不少了. 直接将文件cat到/dev/null都会要几十秒~</p>
<h3>其他</h3>
<p>晚上在Windows平台下一个Debian虚拟机里面配mysqld, 怎么都起不来, 报错是无法绑定端口. 但是显然即使我起了两个mysqld也不会这么费事地排错&#8230;  后来改掉my.cnf里面的bind-address, 将127.0.0.1改为0.0.0.0就正常了&#8230;  都是VM惹的祸&#8230;   </p>
<p>新闻里广汉高铁上有人吸烟导致列车停运. 论坛上一群人骂铁道部胡乱找借口掩盖问题, 另有一群人辩护, 说, 有烟的话列车本来就应该停下来处理, 否则万一火灾就挂了. 这件事我倒有另一个看法, 目前广汉高铁的安检要求太低. 打火机是不能带上飞机的. 既然高铁的速度和飞机也差不了太多, 那么高铁上用打火机我想也应该禁止. 每秒一百米的速度, 如果着火, 绝对响起了通往天国的倒计时了&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xiaket.org/2009/12/31/todays-ideas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pro Django阅读笔记: 第二章 第一部分</title>
		<link>http://blog.xiaket.org/2009/11/21/pro-django-ch2-notes-1/</link>
		<comments>http://blog.xiaket.org/2009/11/21/pro-django-ch2-notes-1/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 11:43:33 +0000</pubDate>
		<dc:creator>xiaket</dc:creator>
				<category><![CDATA[Django开发]]></category>
		<category><![CDATA[Python开发]]></category>
		<category><![CDATA[读书笔记]]></category>
		<category><![CDATA[django-orm]]></category>
		<category><![CDATA[metaprogramming]]></category>

		<guid isPermaLink="false">http://blog.xiaket.org/?p=72</guid>
		<description><![CDATA[Pro Django是由Marty Alchin写的一本关于Django高级技巧的技术书籍. 由Apress出版, 我手头的是09年的第一版. 书籍相关信息及链接如下:



Appress上的书籍主页

<span class="readmore"><a href="http://blog.xiaket.org/2009/11/21/pro-django-ch2-notes-1/" title="Pro Django阅读笔记: 第二章 第一部分">阅读全文——共3784字</a></span>]]></description>
			<content:encoded><![CDATA[<p>Pro Django是由Marty Alchin写的一本关于Django高级技巧的技术书籍. 由Apress出版, 我手头的是09年的第一版. 书籍相关信息及链接如下:</p>
<ul>
<li><a href="http://www.apress.com/book/view/1430210478">Appress上的书籍主页</a></li>
<li><a href="http://prodjango.com/">疑似作者架设的书籍主页</a></li>
<li><a href="http://martyalchin.com/">作者博客</a></li>
</ul>
<p>这本书不适合Django初学者学习, 但是对于已经入门的又需要进一步学习的开发者却很有针对性. 我准备在这儿写一下这本书的读书笔记, 也逼着自己能够继续看完这本书&#8230;第一章基本是闲扯, 虽然概念上很重要, 但是没有提供任何直接的技巧, 就略过了&#8230;这篇文章主要是关于第二章: Django中的python技巧.</p>
<h3>Python中类的创建</h3>
<h4>动态类创建:使用type函数</h4>
<p>要创建一个类, 比较大众化的方法是酱紫的:</p>
<pre class="brush: python;">
&gt;&gt;&gt; class NormalClass(object):
...     print 'Loading NormalClass...',
...     spam = 'eggs'
...     print &quot;done&quot;
...
Loading NormalClass... done
&gt;&gt;&gt; NormalClass
&lt;class '__main__.NormalClass'&gt;
&gt;&gt;&gt; NormalClass.spam
'eggs'
</pre>
<p>除了这种方法之外, 还可以用另外一种方式来创建类:</p>
<pre class="brush: python;">
&gt;&gt;&gt; DynamicClass = type('DynamicClass', (object,), {'spam': 'eggs'})
&gt;&gt;&gt; DynamicClass
&lt;class '__main__.DynamicClass'&gt;
&gt;&gt;&gt; DynamicClass.spam
'eggs'
</pre>
<p>上面这种方面里面用到了type函数. 一般来说, 我们是将一个对象作为参数传递给type函数, 这种情况下type函数的作用是给出这个对象的类型. 而当type接受三个参数时, type函数可视作是class语句的动态形式. 此时, 三个参数依次为新类名, 基类和包含新类属性的字典. 用type来动态构建类是很方便的.</p>
<h4>用元类(metaclass)来改变类的属性</h4>
<p>type实际上是一个元类, 元类是能够创建其它类的类. 元类编程所要实现的目的是在代码运行时而不是在程序编写时创建和改变代码. 例如上面的类定义的例子, 类的名字是代码运行时的一个变量. Python对元类编程的支持是通过允许在类定义里面包括一个元类而实现的. 如果一个类的定义里面包含了对__metaclass__属性的定义, 那么我们不会用默认的type方法来创建这个类, 而是用这个__metaclass__来创建我们定义的类:</p>
<pre class="brush: python;">
&gt;&gt;&gt; class MetaClass(type):
...     def __init__(cls, name, bases, attrs):
...         print 'Defining %s' % cls
...         print 'Name: %s' % name
...         print 'Bases: %s' % (bases, )
...         print 'Attributes:'
...         for (name, value) in attrs.items():
...             print '    %s: %r' % (name, value)
...
&gt;&gt;&gt; class RealClass(object):
...     __metaclass__ = MetaClass
...     spam = 'eggs'
...
Defining &lt;class '__main__.RealClass'&gt;
Name: RealClass
Bases: (&lt;type 'object'&gt;,)
Attributes:
    __module__: '__main__'
    __metaclass__: &lt;class '__main__.MetaClass'&gt;
    spam: 'eggs'
&gt;&gt;&gt; RealClass
&lt;class '__main__.RealClass'&gt;
</pre>
<p>注意哦, 这个类没有实例化, 我们在创建这个类的过程中就执行了MetaClass中的代码. 在这个例子中, MetaClass定义了一个__init__方法, 而在Django内部代码里面, 更多的元类编程是在__new__方法中完成的. 另外, 关于python的元类编程(metaprogramming), 下面有三篇文档, 包括一篇wikipedia上的介绍和IBM DevWorks上两篇不错的文章:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Metaprogramming">Metaprogramming简介</a></li>
<li><a href="http://www.ibm.com/developerworks/cn/linux/l-pymeta/index.html">Python 中的元类编程</a></li>
<li><a href="http://www.ibm.com/developerworks/cn/linux/l-pymeta2/index.html">Python 中的元类编程，第 2 部分</a></li>
</ul>
<h4>实际的元类编程例子: Django中的模型定义</h4>
<p>下面是一段典型的Django创建模型的代码:</p>
<pre class="brush: python;">
class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = [&quot;horn_length&quot;]
        verbose_name_plural = &quot;oxen&quot;
</pre>
<p>现在我们一起来体会下这段代码执行时到底干了什么. 首先需要说明的是, Ox这个类的基类是models.Model, 相关代码在django/db/models/base.py. 而Model这个类是由ModelBase这个元类生成的:</p>
<pre class="brush: python;">
class ModelBase(type):
    &quot;&quot;&quot;
    Metaclass for all models.
    &quot;&quot;&quot;
    def __new__(cls, name, bases, attrs):
+---170 lines: super_new = super(ModelBase, cls).__new__------------------

class Model(object):
    __metaclass__ = ModelBase
    &quot;&quot;&quot;some more code&quot;&quot;&quot;
</pre>
<p>这种布局, 或者说代码结构的好处, 在于在Ox模型的定义过程中隐藏了元类声明, 因为这理应是比较低层的内容, 不应该让普通用户过多干涉. 另一个比较显著的好处在于Ox模型能够方便的继承models.Model里定义的各种方法. 当然, 这样布局后, Ox模型的定义也很清晰易懂, 更pythonic. 读完上面的代码, 会发现类的定义里面还有一个子类, 叫Meta. 简单看了下代码, 虽然名字一样, 但是这段似乎和元类编程没有直接的关系. 尽管Meta里面定义的内容是在ModelBase的__new__方法里面处理而作为_meta来保存的.</p>
<p>关于Django的ORM的进一步讨论会在第三章里面进行~</p>
<h3>各种数据类型的通用方法</h3>
<p>注意下, 这些是约定俗称的通用方法, 而不是确定一定以及肯定有的方法. 对于Django来说, 这些类型都是具有这些方法的, 对于较大的Django的库来说也是这样. 但是不要太想当然&#8230;</p>
<h4>可调用的类型</h4>
<p>此处, 可调用的类型包括函数, 类和类方法都是可调用的. 另外, 如果一个类定义了__call__方法, 那么这个类的实例也是可调用的:</p>
<pre class="brush: python;">
&gt;&gt;&gt; class Multiplier(object):
...     def __init__(self, factor):
...         self.factor = factor
...     def __call__(self, value):
...         return value * self.factor
...
&gt;&gt;&gt; times2 = Multiplier(2)
&gt;&gt;&gt; times2(5)
10
&gt;&gt;&gt; times3 = Multiplier(3)
&gt;&gt;&gt; times3(10)
30
</pre>
<p>在这一段代码中, 我们首先定义了一个乘法器的类, 这个类初始化时接受一个参数, 乘数因子. 这个类的实例能够被调用, 接受一个参数, 被乘数. 例如, 在第7行, 括号中的2是类初始化参数. 初始化后times2是一个Multiplier类的一个实例. 之后我们调用times2(5)是将5作为参数交给Multiplier类中的__call__方法. 另外提一句, Python还提供了一个callable函数来判断一个对象是不是可以被调用的.</p>
<h4>字典</h4>
<p>一般字典类型或者类似字典类型都会提供下面三种方法: __contains__(self, key), __getitem__(self, key), __setitem__(self, key, value). 其中__contains__方法一般通常是通过in运算符使用.</p>
<h4>可迭代的类型</h4>
<p>可迭代的类型是指能够送进for循环的类型. 列表, 元组, 字典等都是可迭代的. 如果你的类想要变成一个可迭代的类型, 那么你需要定义自己的__iter__方法:</p>
<pre class="brush: python;">
&gt;&gt;&gt; class Fibonacci(object):
...     def __init__(self, count):
...         self.count = count
...     def __iter__(self):
...         a, b = 0, 1
...         for x in range(self.count):
...             if x &lt; 2:
...                 yield x
...             else:
...                 c = a + b
...                 yield c
...                 a, b = b, c
...
&gt;&gt;&gt; for x in Fibonacci(5):
...     print x,
...
0 1 1 2 3
&gt;&gt;&gt; for x in Fibonacci(10):
...     print x,
...
0 1 1 2 3 5 8 13 21 34
</pre>
<p>今天就酱紫吧, 明天有时间继续.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xiaket.org/2009/11/21/pro-django-ch2-notes-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
