灵感来自问题系列的隐藏特征…,我很想听听你最喜欢的Django技巧或你知道的不太为人所知但有用的功能。

请在每个答案中只包含一个技巧。 添加Django版本要求(如果有的话)。


当前回答

Instead of using render_to_response to bind your context to a template and render it (which is what the Django docs usually show) use the generic view direct_to_template. It does the same thing that render_to_response does but it also automatically adds RequestContext to the template context, implicitly allowing context processors to be used. You can do this manually using render_to_response, but why bother? It's just another step to remember and another LOC. Besides making use of context processors, having RequestContext in your template allows you to do things like:

<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a> 

这是非常有用的。事实上,+1在一般的视图上。对于简单的应用程序,Django文档大多将它们作为快捷方式显示,甚至没有views.py文件,但你也可以在自己的视图函数中使用它们:

from django.views.generic import simple

def article_detail(request, slug=None):
    article = get_object_or_404(Article, slug=slug)
    return simple.direct_to_template(request, 
        template="articles/article_detail.html",
        extra_context={'article': article}
    )

其他回答

不要编写自己的登录页面。如果你使用django.contrib.auth。

真正的,肮脏的秘密是,如果你也在使用django.contrib。Admin和django.template.loaders.app_directories。Load_template_source在你的模板加载器中,你也可以免费获得你的模板!

# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
    (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
    (r'^accounts/logout/$','views.logout'),
)

安装Django命令扩展和pygraphviz,然后执行以下命令,得到一个非常漂亮的Django模型可视化:

./manage.py graph_models -a -g -o my_project.png

使用数据库迁移。使用南。

我就从我自己的一个建议开始吧:)

在settings.py中使用os.path.dirname()来避免硬编码的dirname。

如果你想在不同的位置运行你的项目,不要在你的settings.py中硬编码路径。如果你的模板和静态文件位于Django项目目录中,在settings.py中使用下面的代码:

# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, "templates"),
)

工作人员:我从视频《Django from the Ground Up》中得到了这个提示。

上下文处理器非常棒。

假设你有一个不同的用户模型,你想包括 在每个回应中。不要这样做:

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模型 并在保存后执行它。