修正django admin raw_id_fields bug

Note: 上午还说 最近更新可能会比较缓慢的 ,结果下午就又上来发了一篇,我自己也很囧啊……

Django Admin中使用ForeignKey是一个比较痛苦的事, 默认使用的是 Select 在数据量比较大的情况下要选中需要选择的对象实在是太难了…… 最近刚刚好又碰到了这个问题,为了图方便,干脆就祭起了 raw_id_fields 这个属性来把外键的选择简化为直接输入id。

可是使用下来出现了问题,如果输入的id无效,Django并不会返回期望的包含错误信息的form,而是直接报了个 django.template.TemplateSyntaxError 的错误。情况很奇怪,FK使用的是 ModelChoiceField ,理论上对无效id的错误已经做了捕捉,那问题到底出在什么地方呢?

继续阅读

在Django的admin change模板中访问对象实例

Django提供了一个比较灵活的Admin系统,除了在admin.py中我们可以做各种各样的定义之外,还可以让我们自己定义指定的app或者Model的模板。比如如果我们需要对一个名为foo的app的admin模板做定制的话,只需要在该app下建立templates/admin/foo/的目录,然后把需要更改的模板放在这儿就可以了。当然前提是基于app的template loader已经加入到settings.py的指定位置。

乍一看你肯定会觉得这是一个相当便民的设计,可是假如你希望在change.html这个模板里访问正在被修改的实例时,问题来了,该对象实例在context中叫什么名称呢?在Django的文档中我没有找到相关的的对象名称,那么按照Generic View的命名规则,应该是叫object吧?试一试,未果,个么尝试obj,再次未果……匆匆忙忙地看了一下admin的源码,也没找到顺眼的名字。怎么办呢?这时候突然想起来admin中的form都是ModelForm,那么应该就可以使用ModelForm的instance属性来获取具体对象实例了吧。试了一下,果然,使用adminform.form.instance能够满足要求。这事就算了了。

今天闲来无事,又想起这个问题,总觉得通过这样的方式访问对象相当丑陋。琢磨了一下,突然想起Django Debug Toolbar提供了查看template context的方法。于是再次打开一个对象的修改页面,使用DDT检测了一下,才发现那对象好好的躺在名为original的字段下。再打开源码核对了一下,终于确定了这个事实。只怪之前看源码的时候只看Context的键值了,居然扰了这么大一弯才回到正轨,劳民伤财,惭愧啊……