灵感来自问题系列的隐藏特征…,我很想听听你最喜欢的Django技巧或你知道的不太为人所知但有用的功能。
请在每个答案中只包含一个技巧。 添加Django版本要求(如果有的话)。
灵感来自问题系列的隐藏特征…,我很想听听你最喜欢的Django技巧或你知道的不太为人所知但有用的功能。
请在每个答案中只包含一个技巧。 添加Django版本要求(如果有的话)。
当前回答
有点晚了。但是Django Canvas最近出来了,它值得在这里占有一席之地。
不要用django-admin.py startproject启动你的项目。相反,你可以使用像Django Canvas这样的工具,用你需要的模块来拼凑一个空白项目。
你去那个网站,勾选一些选项,然后下载一个空白项目,很简单。
它具有所有常见的东西,如南模式迁移和命令扩展,以及这里提到的许多其他最佳实践。另外,它有一个很棒的start.sh/shart.bat脚本,可以安装python, virtualenv, pip, django和任何你需要从windows, osx或linux的新拷贝开始的东西。
其他回答
当将变量从视图传递到模板时,输入响应字典会变得很乏味。我发现使用locals()一次性传递所有局部变量很好。
def show_thing(request, thing_id):
thing = Thing.objects.get(pk=thing_id)
return render_to_response('templates/things/show.html', locals())
(本质上不是一个隐藏的特性,但对于刚接触Python和Django的人来说还是很有帮助的。)
编辑:显然,显式比隐式更好,但这种方法在开发过程中是有帮助的。
使用数据库迁移。使用南。
上下文处理器非常棒。
假设你有一个不同的用户模型,你想包括 在每个回应中。不要这样做:
def myview(request, arg, arg2=None, template='my/template.html'):
''' My view... '''
response = dict()
myuser = MyUser.objects.get(user=request.user)
response['my_user'] = myuser
...
return render_to_response(template,
response,
context_instance=RequestContext(request))
上下文过程使您能够将任何变量传递给您的 模板。我通常把我的放在'my_project/apps/core/context.py中:
def my_context(request):
try:
return dict(my_user=MyUser.objects.get(user=request.user))
except ObjectNotFound:
return dict(my_user='')
在settings.py中,将以下行添加到TEMPLATE_CONTEXT_PROCESSORS中
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
现在每次请求都会自动包含my_user键。
这也是胜利的信号。
几个月前我写了一篇关于这方面的博客文章,所以我只是要剪切和粘贴:
开箱即用的Django提供了几个信号 令人难以置信的有用。你有能力提前做好事情 发布保存,初始化,删除,甚至当请求正在进行时 处理。我们先不讲概念 演示如何使用这些。假设我们有一个博客
from django.utils.translation import ugettext_lazy as _
class Post(models.Model):
title = models.CharField(_('title'), max_length=255)
body = models.TextField(_('body'))
created = models.DateTimeField(auto_now_add=True)
所以你想要通知众多博客中的一个 服务我们已经做了一个新的帖子,重建最近 帖子缓存,并tweet关于它。你有信号 无需添加任何内容即可完成所有这些操作的能力 方法添加到Post类。
import twitter
from django.core.cache import cache
from django.db.models.signals import post_save
from django.conf import settings
def posted_blog(sender, created=None, instance=None, **kwargs):
''' Listens for a blog post to save and alerts some services. '''
if (created and instance is not None):
tweet = 'New blog post! %s' instance.title
t = twitter.PostUpdate(settings.TWITTER_USER,
settings.TWITTER_PASSWD,
tweet)
cache.set(instance.cache_key, instance, 60*5)
# send pingbacks
# ...
# whatever else
else:
cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)
好了,通过定义这个函数并使用 post_init信号,将函数连接到Post模型 并在保存后执行它。
使用信号动态地添加访问方法。
我在django photologue中看到过这种技术:对于添加的任何Size对象,post_init信号都会将相应的方法添加到Image模型中。 如果您添加了一个巨型站点,检索巨型分辨率图片的方法将是image.get_giant_url()。
这些方法是通过调用post_init信号中的add_accessor_methods来生成的:
def add_accessor_methods(self, *args, **kwargs):
for size in PhotoSizeCache().sizes.keys():
setattr(self, 'get_%s_size' % size,
curry(self._get_SIZE_size, size=size))
setattr(self, 'get_%s_photosize' % size,
curry(self._get_SIZE_photosize, size=size))
setattr(self, 'get_%s_url' % size,
curry(self._get_SIZE_url, size=size))
setattr(self, 'get_%s_filename' % size,
curry(self._get_SIZE_filename, size=size))
参见photologue的源代码。用于实际使用的模型。
通过django模板而不是as_(ul|table|p)()渲染表单。
本文展示了如何使用模板来呈现CusstomForms,而不是as_p(), as_table()…
要让它发挥作用,就要改变
从django import newforms as forms到From django import forms from django.newforms.forms import BoundField到from django.forms.forms import BoundField