最喜欢的Django提示和function?

受到“隐藏的特征…”这个问题的启发,我很好奇听到你最喜欢的Django技巧,或者你所知道的一些鲜为人知却很有用的function。

  • 请每个答案只包含一个提示。
  • 添加Django版本的要求,如果有的话。

我只是从我自己的小费开始:)

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

如果您想在不同的位置运行项目,请不要在settings.py中硬编码path。 如果您的模板和静态文件位于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从头开始”得到了这个build议。

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

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

使用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(如redirect)将短路装饰和工作正如你所期望的。

我在网站的所有模板中都使用了一组自定义标签。 寻找一种方法来自动加载它(干,请记住?),我发现以下几点:

 from django import template template.add_to_builtins('project.app.templatetags.custom_tag_module') 

如果你把它放在默认加载的模块中(例如你的主urlconf),你可以在任何模板中使用自定义标记模块中的标记和filter,而不使用{% load custom_tag_module %}

传递给template.add_to_builtins()的参数可以是任何模块path; 您的自定义标签模块不必居住在特定的应用程序中。 例如,它也可以是项目根目录中的一个模块(例如'project.custom_tag_module' )。

Virtualenv + Python =救命,如果你正在使用多个Django项目,并且有可能他们都不依赖相同版本的Django /应用程序。

不要硬编码您的url!

使用url名称 ,而reverse函数来获取URL本身。

当你定义你的URL映射时,给你的URL指定名字。

 urlpatterns += ('project.application.views' url( r'^something/$', 'view_function', name="url-name" ), .... ) 

确保每个url的名称是唯一的。

我通常使用一致的格式“project-appplication-view”,例如线程视图的“cbx-forum-thread”。

更新 (无耻窃取ayaz的另外 ):

这个名字可以在带有url标签的模板中使用。

使用djangodebugging工具栏 。 例如,它允许查看渲染视图时执行的所有SQL查询,也可以查看其中任何一个的堆栈跟踪。

不要编写自己的login页面。 如果您使用的是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'), ) 

上下文处理器非常棒。

假设你有一个不同的用户模型,你想在每个回复中包含这个模型。 而不是这样做:

 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)) 

上下文过程使您能够将任何variables传递给您的模板。 我通常把我的'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自动包含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) 

所以不知何故,你想通知其中一个博客ping服务,我们已经做了一个新的职位,重build最近的postcaching,并鸣叫关于它。 那么有了信号,你就可以完成所有这些工作,而无需在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模型,并在保存后执行它。

当我刚开始的时候,我不知道有一个Paginator ,确保你知道它的存在!

使用IPython跳转到任何级别的代码,并使用IPython的强大function进行debugging。 一旦你安装了IPython就把这个代码放到你想要debugging的地方:

 from IPython.Shell import IPShellEmbed; IPShellEmbed()() 

然后刷新页面,进入你的runserver窗口,你将进入一个交互式的IPython窗口。

我有一个在TextMate中设置的代码段,所以我只需键入ipshell并点击标签。 没有它,我活不下去。

运行一个开发SMTP服务器,只输出发送给它的任何东西(如果你不想在你的开发服务器上实际安装SMTP)。

命令行:

 python -m smtpd -n -c DebuggingServer localhost:1025 

从django-admin文档 :

如果您使用Bash shell,请考虑安装Django bash完成脚本,该脚本位于Django发行版的extras/django_bash_completion中。 它使标签完成django-admin.pymanage.py命令,所以你可以,例如…

  • 键入django-admin.py
  • 按[TAB]查看所有可用的选项。
  • 键入sql ,然后select[TAB],查看名称以sql开头的所有可用选项。

./manage.py runserver_plus附带的./manage.py runserver_plus函数真的很棒。

它创build了一个增强的debugging页面,其中包括使用Werkzeugdebugging器为堆栈中的每个点创build交互式debugging控制台(请参见截图)。 它还提供了一个非常有用的便捷debugging方法dump()来显示关于对象/框架的信息。

在这里输入图像描述

要安装,你可以使用pip:

 pip install django_extensions pip install Werkzeug 

然后将'django_extensions'添加到settings.pyINSTALLED_APPS元组中,并使用新的扩展名启动开发服务器:

 ./manage.py runserver_plus 

这将改变你的debugging方式。

我喜欢使用Pythondebugging器pdb来debuggingDjango项目。

这是学习如何使用它的有用链接: http : //www.ferg.org/papers/debugging_in_python.html

当试图在Django和其他应用程序之间交换数据时, request.raw_post_data是一个好朋友。 使用它来接收和自定义处理XML数据。

文档: http : //docs.djangoproject.com/en/dev/ref/request-response/

在视图代码中添加assert False来转储debugging信息。

与Django一起使用Jinja2 。

如果你发现Django的模板语言非常有限制(像我一样),那么你就不必拘泥于此。 Django是灵活的,模板语言与系统的其他部分松散耦合,所以只需插入另一个模板语言并使用它来呈现您的http响应!

我使用Jinja2 ,它几乎就像django模板语言的动力版本,它使用相同的语法,并允许您在if语句中使用expression式! 没有更多的自定义if-tag,如if_item_in_list ! 你可以简单地说%{ if item in list %} ,或者{% if object.field < 10 %}

但这不是全部; 它有更多的function,以缓解模板创build,我不能去所有这些在这里。

这增加了上面关于Django URL名称和反向URL调度的回复。

URL名称也可以在模板中有效使用。 例如,对于给定的URL模式:

 url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team') 

您可以在模板中具有以下内容:

 <a href="{% url project_team project.id %}">Team</a> 

由于Django“views”只需要返回HttpResponse的可调用对象,就可以轻松创build类似于Ruby on Rails和其他框架的基于类的视图。

有几种方法来创build基于类的视图,这是我最喜欢的:

 from django import http class RestView(object): methods = ('GET', 'HEAD') @classmethod def dispatch(cls, request, *args, **kwargs): resource = cls() if request.method.lower() not in (method.lower() for method in resource.methods): return http.HttpResponseNotAllowed(resource.methods) try: method = getattr(resource, request.method.lower()) except AttributeError: raise Exception("View method `%s` does not exist." % request.method.lower()) if not callable(method): raise Exception("View method `%s` is not callable." % request.method.lower()) return method(request, *args, **kwargs) def get(self, request, *args, **kwargs): return http.HttpResponse() def head(self, request, *args, **kwargs): response = self.get(request, *args, **kwargs) response.content = '' return response 

您可以在基本视图中添加各种其他的东西,如条件请求处理和授权。

一旦你有了你的视图设置你的urls.py将如下所示:

 from django.conf.urls.defaults import * from views import MyRestView urlpatterns = patterns('', (r'^restview/', MyRestView.dispatch), ) 

而不是使用render_to_response将您的上下文绑定到模板并呈现它(这是Django文档通常显示的)使用通用视图direct_to_template 。 它的作用与render_to_response一样,但也自动将RequestContext添加到模板上下文中,隐式允许使用上下文处理器。 您可以使用render_to_response手动执行此操作,但为什么要麻烦? 这只是另一个记忆和另一个LOC。 除了使用上下文处理器外,在模板中使用RequestContext还可以执行如下操作:

 <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} ) 

我没有足够的信誉来回复有问题的评论,但是需要注意的是,如果您要使用Jinja ,则它不支持模板块名称中的“ – ”字符,而Django则支持。 这导致了我很多的问题,并浪费了时间来追踪它产生的非常模糊的错误信息。

网页devise应用程序在开始devise您的网站时非常有用。 一旦导入,您可以添加这个来生成示例文本:

 {% load webdesign %} {% lorem 5 p %} 

django.db.models.get_model允许您在不导入模型的情况下检索模型。

James展示了它的使用方式: “Django提示:编写更好的模板标签 – 迭代4” 。

大家都知道有一个你可以使用“manage.py runserver”运行的开发服务器,但是你知道有一个服务于静态文件(CSS / JS / IMG)的开发视图吗?

新手总是困惑,因为Django没有任何方式来提供静态文件。 这是因为开发团队认为这是一个现实生活Web服务器的工作。

但是在开发时,你可能不想设置Apache + mod_wisgi,这很重。 然后,您可以将以下内容添加到urls.py:

 (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}), 

您的CSS / JS / IMG将在www.yoursite.com/site_media/上提供。

当然,不要在生产环境中使用它。

我从sorl-thumbnails应用程序的文档中学到了这个。 您可以使用模板标记中的“as”关键字来使用模板中其他地方的调用结果。

例如:

 {% url image-processor uid as img_src %} <img src="{% thumbnail img_src 100x100 %}"/> 

这在Django的templatetag文档中已经提到过了,但是仅仅提到了循环。 他们不会说你可以在其他地方(任何地方)使用它。

django.views.generic.list_detail.object_list – 它为分页提供了所有的逻辑和模板variables(我曾经写过的那个 – 一千次 – 现在是痛苦的)。 包装它允许您需要的任何逻辑。 这个gem在我的“search结果”页面中为我节省了许多小时的一对一错误,并使得视图代码更加清晰。

PyCharm IDE是一个很好的编码和debugging环境,并且内置了对Django的支持。

使用xml_models来创build使用XML REST API后端(而不是SQL)的Django模型。 这非常有用,特别是在build模第三方API时 – 您可以获得与以前相同的所有QuerySet语法。 您可以从PyPI安装它。

来自API的XML:

 <profile id=4> <email>joe@example.com</email> <first_name>Joe</first_name> <last_name>Example</last_name> <date_of_birth>1975-05-15</date_of_birth> </profile> 

现在在python中:

 class Profile(xml_models.Model): user_id = xml_models.IntField(xpath='/profile/@id') email = xml_models.CharField(xpath='/profile/email') first = xml_models.CharField(xpath='/profile/first_name') last = xml_models.CharField(xpath='/profile/last_name') birthday = xml_models.DateField(xpath='/profile/date_of_birth') finders = { (user_id,): settings.API_URL +'/api/v1/profile/userid/%s', (email,): settings.API_URL +'/api/v1/profile/email/%s', } profile = Profile.objects.get(user_id=4) print profile.email # would print 'joe@example.com' 

它也可以处理关系和集合。 我们每天都在大量使用的生产代码中使用它,所以即使它是testing版,也是非常有用的。 它也有一套很好的存根,可以在你的testing中使用。

(声明:虽然我不是这个库的作者,但我现在是一个提交者,做了一些小的提交)

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