Favorite Django Tips & Features?
受问题系列"隐藏的……特征"的启发,我很想知道你最喜欢的django技巧,或者你知道的一些不太知名但有用的特征。
- 请每个答案只包括一个提示。
- 如果有,添加django版本要求。
我要从我自己的小费开始:)
在settings.py中使用os.path.dirname()以避免硬编码的dirname。
不要在设置中硬编码路径。如果要在不同的位置运行项目,请复制。如果模板和静态文件位于django项目目录中,请使用settings.py中的以下代码:
1 2 3 4 5 6 7 8 9 | # 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命令扩展和pygraphviz,然后发出以下命令以获得非常漂亮的django模型可视化效果:
1 | ./manage.py graph_models -a -g -o my_project.png |
使用django恼人的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @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(如重定向)会使装饰器短路,并按预期工作。
我在网站的所有模板上都使用了一组自定义标记。寻找一种自动加载的方法(干燥,记得吗?),我发现了以下内容:
1 2 | from django import template template.add_to_builtins('project.app.templatetags.custom_tag_module') |
如果将其放入默认加载的模块中(例如,您的主urlconf),那么您可以在任何模板中使用自定义标记模块中的标记和过滤器,而不使用
传递给
virtualenv+python=life saver如果您正在处理多个django项目,并且可能它们都不依赖于同一版本的django/an应用程序。
不要硬编码你的网址!
使用url名称代替,使用
定义URL映射时,请为URL命名。
1 2 3 4 | urlpatterns += ('project.application.views' url( r'^something/$', 'view_function', name="url-name" ), .... ) |
确保每个URL的名称都是唯一的。
我通常有一个一致的格式"项目应用视图",例如线程视图的"CBX论坛线程"。
更新(无耻地窃取了Ayaz的附加内容):
此名称可以在带有
使用Django调试工具栏。例如,它允许查看呈现视图时执行的所有SQL查询,还可以查看其中任何一个查询的stacktrace。
不要编写自己的登录页面。如果您正在使用django.contrib.auth。
真正肮脏的秘密是,如果您还使用django.contrib.admin和django.template.loaders.app_directories.load_template_source,那么您也可以免费获取模板!
1 2 3 4 5 | # somewhere in urls.py urlpatterns += patterns('django.contrib.auth', (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}), (r'^accounts/logout/$','views.logout'), ) |
上下文处理器非常棒。
假设你有一个不同的用户模型,你想包括在每个回应中。而不是这样做:
1 2 3 4 5 6 7 8 9 | 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)) |
上下文过程使您能够将任何变量传递给模板。我通常把我的放在
1 2 3 4 5 | def my_context(request): try: return dict(my_user=MyUser.objects.get(user=request.user)) except ObjectNotFound: return dict(my_user='') |
在您的
1 2 3 4 | TEMPLATE_CONTEXT_PROCESSORS = ( 'my_project.apps.core.context.my_context', ... ) |
现在,每次发出请求时,都会自动包含
几个月前我写了一篇关于这个的博客文章,所以我只想剪切粘贴:
开箱即用的Django给你几个信号非常有用。你有能力在post save、init、delete,甚至当请求处理。所以让我们远离这些概念演示如何使用这些。假设我们有一个博客
1 2 3 4 5 | 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服务我们已经发了一个新的帖子,重建最近的发布缓存,并在tweet上发布。好吧,有信号的话不需要添加任何方法到Post类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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模型保存后执行。
当我刚开始的时候,我不知道有一个异教徒,确保你知道它的存在!!
使用ipython可以在任何级别跳到代码中,并使用ipython的强大功能进行调试。一旦安装了IPython,只要将此代码放入要调试的任何位置即可:
1 | from IPython.Shell import IPShellEmbed; IPShellEmbed()() |
然后,刷新页面,转到您的runserver窗口,您将进入一个交互式的ipython窗口。
我在textmate中设置了一个代码片段,所以我只需键入ipshell并点击tab。没有它我活不下去。
运行一个只输出发送给它的内容的开发SMTP服务器(如果您不想在您的开发服务器上实际安装SMTP)。
命令行:
1 | python -m smtpd -n -c DebuggingServer localhost:1025 |
从Django管理文档:
如果使用bash shell,请考虑安装django bash完成脚本,该脚本位于django发行版的
django-admin.py 型。- 按[tab]查看所有可用选项。
- 键入
sql ,然后键入〔tab〕,查看名称以sql 开头的所有可用选项。
django ou扩展版附带的
它创建了一个增强的调试页面,除其他外,该页面使用Werkzeug调试器为堆栈中的每个点创建交互式调试控制台(请参见屏幕截图)。它还为显示对象/帧信息提供了一种非常有用的方便调试方法
要安装,可以使用pip:
1 2 | pip install django_extensions pip install Werkzeug |
然后将
1 | ./manage.py runserver_plus |
这将更改调试方式。
我喜欢使用python调试器pdb来调试django项目。
这是一个学习如何使用它的有用链接:http://www.ferg.org/papers/debugging_in_python.html
当试图在Django和另一个应用程序之间交换数据时,
文档:http://docs.djangoproject.com/en/dev/ref/request-response(请求-响应)/
在视图代码中添加
在Django旁边使用Jinja2。
如果您发现django模板语言非常限制(像我!)那你就不必被它困住了。Django是灵活的,模板语言与系统的其他部分松散耦合,因此只需插入另一种模板语言,并使用它来呈现HTTP响应!
我使用jinja2,它几乎就像是Django模板语言的加电版本,它使用相同的语法,并且允许您在if语句中使用表达式!如果标签如
但这并不是全部;它有更多的特性来简化模板的创建,我不能在这里浏览所有的特性。
这增加了上面关于django url名称和反向url调度的回复。
URL名称也可以在模板中有效地使用。例如,对于给定的URL模式:
1 | url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team') |
模板中可以包含以下内容:
1 | Team |
由于django"views"只需要是返回httpresponse的可调用的,所以您可以轻松地创建基于类的视图,如RubyonRails和其他框架中的视图。
有几种方法可以创建基于类的视图,这是我最喜欢的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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就会变成这样:
1 2 3 4 5 6 | from django.conf.urls.defaults import * from views import MyRestView urlpatterns = patterns('', (r'^restview/', MyRestView.dispatch), ) |
不要使用
1 | A frog |
这是非常有用的。实际上,一般来说+1是通用视图。Django文档大多将它们显示为快捷方式,即使对于简单的应用程序没有views.py文件,也可以在自己的视图功能中使用它们:
1 2 3 4 5 6 7 8 | 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支持。这给我带来了很多问题,也浪费了很多时间来跟踪它生成的非常模糊的错误消息。
每个人都知道有一个可以用"manage.py run server"运行的开发服务器,但是您知道有一个为静态文件(css/js/img)提供服务的开发视图吗?
新来者总是感到困惑,因为Django没有任何方式来提供静态文件。这是因为开发团队认为这是一个真实的Web服务器的工作。
但是在开发时,您可能不想设置apache+mod_wisgi,这很重。然后您可以将以下内容添加到urls.py中:
1 2 | (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}), |
您的css/js/img将在www.your site.com/site_media/上提供。
当然,不要在生产环境中使用它。
WebDesign应用程序在开始设计网站时非常有用。导入后,可以添加此内容以生成示例文本:
1 2 | {% load webdesign %} {% lorem 5 p %} |
James展示了它是多么的方便:"Django提示:写更好的模板标签-迭代4"。
我从SORL缩略图应用程序的文档中学习了这个。您可以使用模板标记中的"as"关键字来使用模板中其他地方的调用结果。
例如:
1 2 | {% url image-processor uid as img_src %} <img src="{% thumbnail img_src 100x100 %}"/> |
在传递django templatetag文档时提到了这一点,但仅参考循环。他们不会说你可以在其他地方(任何地方)使用这个。也。
pycharm-ide是一个很好的编程环境,特别是调试环境,内置了对django的支持。
django.views.generic.list_detail.object_list——它提供了所有用于分页的逻辑和模板变量(这是我写过一千次的任务之一)。包装它允许您需要的任何逻辑。这个gem为我的"搜索结果"页面中的一个错误节省了许多小时的调试时间,并使视图代码在这个过程中更加清晰。
使用数据库迁移。南部使用。
使用XML_模型创建使用XML REST API后端(而不是SQL后端)的Django模型。这非常有用,尤其是在建模第三方API时——您得到的查询集语法完全相同。您可以从pypi安装它。
来自API的XML:
1 2 3 4 5 6 | <profile id=4> 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中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 '[email protected]' |
它还可以处理关系和集合。我们每天都在大量使用的生产代码中使用它,所以即使它是beta版本,它也是非常有用的。它还有一组很好的存根,可以在测试中使用。
(免责声明:虽然我不是此库的作者,但我现在是一名提交者,做了一些小的承诺)
刚刚找到这个链接:http://lincolnloop.com/django best practices/目录-"django best practices"。
在Django1.2+中使用.exists(),在以前的版本中使用.count(),而不是评估整个查询集以检查是否返回任何结果。
exists()和count()都清除order by子句,并从db中检索单个整数。但是exists()将始终返回1,其中as count可能返回更高的值,对这些值手动应用限制。source for has_result used in exists()and get_count used in count()for好奇的人。
因为它们都返回一个整数,所以没有模型实例化,也没有在内存中加载模型属性,也没有在数据库和应用程序之间传递大的文本字段。
如果已经计算了查询,.count()计算len(缓存的结果),.exists()计算bool(缓存的结果)
不高效-示例1
1 2 3 | books = Books.objects.filter(author__last_name='Brown') if books: # Do something |
不高效-示例2
1 2 3 | books = Books.objects.filter(author__last_name='Brown') if len(books): # Do something |
高效-示例1
1 2 3 | books = Books.objects.filter(author__last_name='Brown') if books.count(): # Do something |
高效-示例2
1 2 3 | books = Books.objects.filter(author__last_name='Brown') if books.exists(): # Do something |
如果对模型进行更改
1 2 3 | ./manage.py dumpdata appname > appname_data.json ./manage.py reset appname django-admin.py loaddata appname_data.json |
从settings.py中删除数据库访问信息
我在Django站点的
您还可以通过环境变量传递数据库连接信息,甚至只是配置文件的键或路径,并在
例如,以下是我拉入数据库配置文件的方式:
1 2 3 4 5 6 7 8 9 10 11 12 | g = {} dbSetup = {} execfile(os.environ['DB_CONFIG'], g, dbSetup) if 'databases' in dbSetup: DATABASES = dbSetup['databases'] else: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # ... } } |
不用说,您需要确保除了db admins和django本身之外,任何用户都无法访问
我要做的另一件事是使用单独的用户执行数据库管理任务,而不是其他任何任务。在我的
1 2 3 4 5 6 7 8 9 10 11 12 | # Find a database configuration, if there is one, and set it in the environment. adminDBConfFile = '/etc/django/db_admin.py' dbConfFile = '/etc/django/db_regular.py' import sys import os def goodFile(path): return os.path.isfile(path) and os.access(path, os.R_OK) if len(sys.argv) >= 2 and sys.argv[1] in ["syncdb","dbshell","migrate"] \ and goodFile(adminDBConfFile): os.environ['DB_CONFIG'] = adminDBConfFile elif goodFile(dbConfFile): os.environ['DB_CONFIG'] = dbConfFile |
其中,
(抄自我对另一个问题的回答)
使用信号动态添加访问器方法。
我在django photologue中看到了这种技术:对于添加的任何大小的对象,post-init信号都会将相应的方法添加到图像模型中。如果您添加一个站点巨人,那么以巨分辨率检索图片的方法将是
这些方法是通过从
1 2 3 4 5 6 7 8 9 10 | 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.models的源代码。
不要在本地主机上运行django dev服务器,而是在适当的网络接口上运行它。例如:
1 | python manage.py runserver 192.168.1.110:8000 |
或
1 | python manage.py runserver 0.0.0.0:8000 |
然后,您不仅可以轻松地使用fiddler(http://www.fiddler2.com/fiddler2/)或其他工具(如http debugger(http://www.http debugger.com/)来检查您的http头,还可以从LAN上的其他计算机访问您的dev站点进行测试。
尽管dev服务器是最小且相对安全的,但是请确保您受到防火墙的保护。
在自定义视图装饰器中使用
1 2 3 4 5 6 7 8 9 10 | try: from functools import wraps except ImportError: from django.utils.functional import wraps # Python 2.3, 2.4 fallback. def view_decorator(fun): @wraps(fun) def wrapper(): # here goes your decorator's code return wrapper |
注意:如果作者没有定义
1 2 3 | from django.utils.decorators import available_attrs ... @wraps(fun, assigned=available_attrs(fun)) |
Django调试工具栏非常棒。它实际上并不是一个工具栏,而是一个侧窗格,告诉您有关所查看页面的各种信息—数据库查询、发送到模板的上下文变量、信号等等。
使用"apps"文件夹组织应用程序而不编辑pythonpath
当我想像这样整理我的文件夹时,这很方便:
1 2 3 4 5 6 | apps/ foo/ bar/ site/ settings.py urls.py |
无需覆盖pythonpath或在每次导入时添加应用程序,如:
1 2 | from apps.foo.model import * from apps.bar.forms import * |
在您的设置中.py add
1 2 3 4 | import os import sys PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, os.path.join(PROJECT_ROOT,"apps")) |
你准备好出发了:—)
我在http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps上看到了这个。/
在生产环境中自动设置"debug"属性(settings.py)
1 2 3 4 5 6 | import socket if socket.gethostname() == 'productionserver.com': DEBUG = False else: DEBUG = True |
作者:http://nicksergeant.com/2008/automatically-setting-debug-in-your-django-app-based-on-server-hostname/
通过django模板呈现表单,而不是使用(ul table p)()。
本文介绍了如何用模板来代替
改变它的工作方式
from django import newforms as forms 至from django import forms 。from django.newforms.forms import BoundField 至from django.forms.forms import BoundField 。
在URLCONF中使用REVERSE。
这是其中一个技巧,我不明白为什么它不是默认的。
这里有一个链接,指向我在哪里找到它:http://andr.in/2009/11/21/calling-reverse-in-django/
下面是代码段:
1
2
3
4
5
6
7
8
9
10
11
12 from django.conf.urls.defaults import *
from django.core.urlresolvers import reverse
from django.utils.functional import lazy
from django.http import HttpResponse
reverse_lazy = lazy(reverse, str)
urlpatterns = patterns('',
url(r'^comehere/', lambda request: HttpResponse('Welcome!'), name='comehere'),
url(r'^$', 'django.views.generic.simple.redirect_to',
{'url': reverse_lazy('comehere')}, name='root')
)
使用DjangoreCipe管理项目
- 如果你正在写一个新的应用程序,这个方法使得在项目外测试非常容易。
- 它允许您管理项目的依赖关系(例如,它应该依赖于某个应用程序的哪个版本)
你要开始做的就是:
创建一个buildout.cfg,其中包含以下内容:
1 2 3 4 5 6 7 8 | [buildout] parts=django [django] recipe=djangorecipe version=1.1.1 project=my_new_site settings=development |
就是这样。现在,您应该有一个新文件夹"我的新站点",这是您的新Django 1.1.1项目,在./bin中,您将找到在正常安装中替换manage.py的
有什么好处?假设您希望在您的项目中使用类似于django comment spamfighter的东西。你要做的就是把buildout.cfg改成这样:
1 2 3 4 5 6 7 8 9 10 | [buildout] parts=django [django] recipe=djangorecipe version=1.1.1 project=my_new_site settings=development eggs= django-comments-spamfighter==0.4 |
注意,我所做的只是添加最后两行,即django部分还应该在0.4版中包含django comments spamfighter包。下次运行
DjangoreCipe也适用于使用mod wsgi部署项目。只需将
如果您将
如果你想在一个独立的环境中开发一个应用程序来进行调试等,Jakob Kaplan Moss在他的博客上有一个非常完整的教程。
这是一种非常简单的方法,不必再在Python外壳中导入另一个模型。
首先,安装ipython(如果你不使用ipython,你怎么了?).接下来,在django项目目录中创建一个python脚本ipythonrc.py,其中包含以下代码:
1 2 3 4 | from django.db.models.loading import get_models for m in get_models(): globals()[m.__name__] = m #NOTE: if you have two models with the same name you'll only end up with one of them |
然后,在~/.ipython/ipythonrc文件中,将以下代码放入"要加载和执行的python文件"部分:
1 | execfile /path/to/project/ipythonrc.py |
现在,每次启动ipython或运行
您还可以在ipythonrc.py文件中放入您经常执行的任何其他代码,以节省您的时间。
更改init上的django表单字段属性
有时向窗体类传递额外的参数很有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django import forms from mymodels import Group class MyForm(forms.Form): group=forms.ModelChoiceField(queryset=None) email=forms.EmailField() some_choices=forms.ChoiceField() def __init__(self,my_var,*args,**kwrds): super(MyForm,self).__init__(*args,**kwrds) self.fields['group'].queryset=Group.objects.filter(...) self.fields['email'].widget.attrs['size']='50' self.fields['some_choices']=[[x,x] for x in list_of_stuff] |
来源:dzone片段
Pycharm和Wingware IDE是一个很好的工具,如果你有钱支付许可证。
因为我是一个糟糕的开发人员,所以我将pydev与eclipse结合使用。
来自https://github.com/django-extensions/django-extensions的
很少有漂亮的
shell_plus —从所有已安装的应用程序自动导入模型show_urls -打印项目中所有应用程序中定义的所有URLrunscript —在项目上下文中运行任何脚本(您可以使用模型和其他与django相关的模块)
使用isapi wsgi和django pyodbc在Windows上使用IIS和SQL Server运行django!
参加聚会有点晚。但姜戈画布最近问世了,它应该在这里占有一席之地。
不要从
你去那个网站,勾选一些选项,然后下载一个空白项目,很简单。
它具有所有常见的功能,比如南模式迁移和命令扩展,以及这里提到的许多其他最佳实践。另外,它还有一个很好的
如果你还没读过的话,请继续读《姜戈》。它包含了很多关于Django陷阱的有用信息。
使用异步任务。芹菜用
为具有相同结构的旧表集创建动态模型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class BaseStructure(models.Model): name = models.CharField(max_length=100) address = models.CharField(max_length=100) class Meta: abstract=True class DynamicTable(models.Model): table_name = models.CharField(max_length=20) def get_model(self): class Meta: managed=False table_name=self.table_name attrs = {} attrs['Meta'] = Meta # type(new_class_name, (base,classes), {extra: attributes}) dynamic_class = type(self.table_name, (BaseStructure,), attrs) return dynamic_class customers = DynamicTable.objects.get(table_name='Customers').get_model() me = customers.objects.get(name='Josh Smeaton') me.address = 'Over the rainbow' me.save() |
这假设您有具有相同结构的遗留表。不是创建一个模型来包装每个表,而是定义一个基本模型,并动态构造与特定表交互所需的类。
当将变量从一个视图传递到一个模板时,响应字典可能变得单调乏味,无法输入。我发现使用
1 2 3 | def show_thing(request, thing_id): thing = Thing.objects.get(pk=thing_id) return render_to_response('templates/things/show.html', locals()) |
(本身并不是隐藏的特性,但是对于Python和/或Django来说,它还是很有用的。)
编辑:显然,显式比隐式更好,但这种方法在开发过程中会有所帮助。
dir()提升值错误()
为了调试/探索开发过程中的状态,我使用以下技巧:
1 2 3 4 5 | ... to_see = dir(inspect_this_thing) to_see2 = inspect_this_thing.some_attribute raise ValueError("Debugging") ... |
当您在Django的某些部分工作,这些部分没有很好的文档记录时,这尤其有用(Form.Changed_字段是我最近使用的字段)。
()
不要为模板上下文写出每个变量,而是使用python builtin locals()命令,该命令为您创建一个字典:
1 2 3 4 5 6 7 8 9 10 | #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没有应用程序设置,所以我做了自己的应用程序设置.py检测。在settings.py的底部,我添加了以下代码:
1 2 3 4 5 6 7 8 9 10 11 | import sys, os # Append application settings without triggering the __init__. for installed_app in INSTALLED_APPS: # Ignore django applications if not installed_app.startswith('django.'): # Find the app (and the settings file) for path in sys.path: path = os.path.join(path, installed_app, 'app_settings.py') if os.path.isfile(path): # Application settings found exec open(path).read() |
它在所有已安装的应用程序中检测app_settings.py。它不会导入,而是读取app_设置文件的内容并以内联方式执行。如果直接导入app_设置,将引发所有类型的django导入错误(因为django尚未初始化)。
所以我的app/app_settings.py将如下所示:
1 2 3 | MIDDLEWARE_CLASSES += ( 'app.middleware.FancyMiddleware', ) |
现在只需将应用程序添加到已安装的应用程序中,而不必查找所有应用程序设置并将它们添加到settings.py(中间件、URL…)
注意:如果django有一个附加额外设置的钩子,那么最好在启动时(或运行时)添加应用程序设置。