灵感来自问题系列的隐藏特征…,我很想听听你最喜欢的Django技巧或你知道的不太为人所知但有用的功能。
请在每个答案中只包含一个技巧。 添加Django版本要求(如果有的话)。
灵感来自问题系列的隐藏特征…,我很想听听你最喜欢的Django技巧或你知道的不太为人所知但有用的功能。
请在每个答案中只包含一个技巧。 添加Django版本要求(如果有的话)。
当前回答
Django调试工具栏真的很棒。它实际上并不是一个工具栏,而是一个侧栏,告诉您是什么带来了您正在查看的页面的各种信息——DB查询、发送到模板的上下文变量、信号等等。
其他回答
不要编写自己的登录页面。如果你使用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'),
)
dir()和提高评估误差()
为了在开发过程中调试/探索事物的状态,我使用了以下技巧:
...
to_see = dir(inspect_this_thing)
to_see2 = inspect_this_thing.some_attribute
raise ValueError("Debugging")
...
当你处理django中没有很好文档的部分时,这是特别有用的。changed_fields是我最近使用的一个)。
当地人()。
使用python内置的locals()命令为你创建一个字典,而不是为模板上下文写出每个变量:
#This is tedious and not very DRY
return render_to_response('template.html', {"var1": var1, "var2":var2}, context_instance=RequestContext(request))
#95% of the time this works perfectly
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
#The other 4.99%
render_dict = locals()
render_dict['also_needs'] = "this value"
return render_to_response('template.html', render_dict, context_instance=RequestContext(request))
使用django-annoying的render_to装饰器而不是render_to_response。
@render_to('template.html')
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return {'bars': bars}
# equals to
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return render_to_response('template.html',
{'bars': bars},
context_instance=RequestContext(request))
编辑后指出,返回一个HttpResponse(例如重定向)将使装饰器短路,并像您期望的那样工作。
当Django和另一个应用程序交换数据时,请求。Raw_post_data是一个好朋友。使用它来接收和自定义处理(比如XML数据)。
文档: http://docs.djangoproject.com/en/dev/ref/request-response/
上下文处理器非常棒。
假设你有一个不同的用户模型,你想包括 在每个回应中。不要这样做:
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模型 并在保存后执行它。