最喜欢的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.py
和manage.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.py
的INSTALLED_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中使用。
(声明:虽然我不是这个库的作者,但我现在是一个提交者,做了一些小的提交)
使用数据库迁移。 使用南方 。