受到问题系列“隐藏的......的特征”的启发,我很想知道你最喜欢的Django技巧或者你知道的鲜为人知但有用的功能。
答案 0 :(得分:222)
我将从我自己的小费开始:)
在settings.py中使用os.path.dirname()来避免使用硬编码的dirnames。
如果要在不同位置运行项目,请不要在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”获得了此提示。
答案 1 :(得分:130)
安装Django Command Extensions和pygraphviz,然后发出以下命令以获得非常漂亮的Django模型可视化:
./manage.py graph_models -a -g -o my_project.png
答案 2 :(得分:119)
使用django-annoying's 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(例如重定向)会使装饰器短路并按预期工作。
答案 3 :(得分:102)
我在网站的模板上使用了一组自定义标记。正在寻找一种自动加载它的方法(干,记得吗?),我发现了以下内容:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
如果你把它放在一个默认加载的模块中(例如你的主urlconf),你可以在任何模板中使用自定义标签模块中的标签和过滤器,而不使用{% load custom_tag_module %}
。
传递给template.add_to_builtins()
的参数可以是任何模块路径;您的自定义标记模块不必存在于特定的应用程序中。例如,它也可以是项目根目录中的模块(例如'project.custom_tag_module'
)。
答案 4 :(得分:97)
Virtualenv + Python =生命保护程序如果您正在处理多个Django项目,并且它们可能都不依赖于相同版本的Django /应用程序。
答案 5 :(得分:88)
不要硬编码您的网址!
定义URL映射时,请为您的URL指定名称。
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
确保每个网址的名称都是唯一的。
我通常使用一致的格式“project-appplication-view”,例如“cbx-forum-thread”用于线程视图。
更新(无耻地窃取ayaz's addition):
此名称可用于url
tag的模板。
答案 6 :(得分:82)
使用django debug toolbar。例如,它允许查看渲染视图时执行的所有SQL查询,您还可以查看其中任何一个的堆栈跟踪。
答案 7 :(得分:80)
不要编写自己的登录页面。如果你正在使用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'),
)
答案 8 :(得分:67)
假设您有不同的用户模型并且想要包含 在每一个回应中。而不是这样做:
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)
所以不知怎的,你想要通知众多博客之一 服务我们已经发了一个新帖子,重建最新的 发布缓存,并发布有关它的推文。你有信号 能够在不添加任何内容的情况下完成所有这些操作 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模型 并在保存后执行。
答案 9 :(得分:57)
当我刚开始时,我不知道有Paginator,确保你知道它的存在!!
答案 10 :(得分:47)
使用IPython跳转到任何级别的代码,并使用IPython的强大功能进行调试。一旦安装了IPython,只需将此代码放在要调试的位置:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
然后,刷新页面,转到runserver窗口,您将进入交互式IPython窗口。
我在TextMate中设置了一个代码段,所以我只需输入ipshell并点击tab。没有它我就活不下去。
答案 11 :(得分:43)
运行开发SMTP服务器,该服务器只输出发送给它的任何内容(如果您不想在开发服务器上实际安装SMTP。)
命令行:
python -m smtpd -n -c DebuggingServer localhost:1025
答案 12 :(得分:41)
如果您使用Bash shell,请考虑安装Django bash完成脚本,该脚本位于Django发行版中的extras/django_bash_completion
。它支持完成django-admin.py
和manage.py
命令的制表符,因此您可以...例如......
django-admin.py
。sql
,然后按[TAB],查看名称以sql
开头的所有可用选项。答案 13 :(得分:40)
django_extensions附带的./manage.py runserver_plus
便利非常棒。
它创建了一个增强的调试页面,除其他外,它使用Werkzeug调试器为堆栈中的每个点创建交互式调试控制台(参见屏幕截图)。它还提供了一个非常有用的便捷调试方法dump()
,用于显示有关对象/框架的信息。
要安装,您可以使用pip:
pip install django_extensions
pip install Werkzeug
然后将'django_extensions'
添加到INSTALLED_APPS
中的settings.py
元组,并使用新扩展程序启动开发服务器:
./manage.py runserver_plus
这将改变您的调试方式。
答案 14 :(得分:37)
当尝试在Django和其他应用程序之间交换数据时,request.raw_post_data
是一个好朋友。用它来接收和自定义处理XML数据。
文档: http://docs.djangoproject.com/en/dev/ref/request-response/
答案 15 :(得分:37)
我喜欢使用Python调试器pdb来调试Django项目。
这是学习如何使用它的有用链接:http://www.ferg.org/papers/debugging_in_python.html
答案 16 :(得分:35)
在视图代码中添加assert False
以转储调试信息。
答案 17 :(得分:35)
与Django一起使用Jinja2。
如果你发现Django模板语言极其严格(像我一样!)那么你就不必被它困住了。 Django非常灵活,模板语言与系统的其他部分松散耦合,因此只需插入另一种模板语言并使用它来呈现您的http响应!
我使用Jinja2,它几乎就像是django模板语言的加电版本,它使用相同的语法,并允许你在if语句中使用表达式!不再制作自定义if标签,例如if_item_in_list
!您可以简单地说%{ if item in list %}
或{% if object.field < 10 %}
。
但并非全部;它有更多的功能来简化模板创建,我不能在这里完成所有这些功能。
答案 18 :(得分:33)
这会在上面的回复中添加Django URL names and reverse URL dispatching。
URL名称也可以在模板中有效使用。例如,对于给定的URL模式:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
您可以在模板中使用以下内容:
<a href="{% url project_team project.id %}">Team</a>
答案 19 :(得分:27)
由于Django“views”只需要是返回HttpResponse的callables,因此您可以轻松地创建类似于Ruby on Rails和其他框架的基于类的视图。
有几种方法可以创建基于类的视图,这是我的最爱:
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),
)
答案 20 :(得分:21)
不使用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}
)
答案 21 :(得分:20)
我没有足够的声誉来回复相关评论,但重要的是要注意,如果您要使用Jinja,则不支持模板块名称中的“ - ”字符,而Django确实如此。这给我带来了很多问题,浪费时间试图追踪它产生的非常模糊的错误信息。
答案 22 :(得分:19)
每个人都知道有一个可以使用“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 /.
上提供当然,不要在生产环境中使用它。
答案 23 :(得分:19)
django.db.models.get_model
允许您在不导入模型的情况下检索模型。
詹姆斯表明它是多么方便:"Django tips: Write better template tags — Iteration 4 "。
答案 24 :(得分:19)
在开始设计您的网站时,webdesign app非常有用。导入后,您可以添加它以生成示例文本:
{% load webdesign %}
{% lorem 5 p %}
答案 25 :(得分:18)
我从sorl-thumbnails应用的文档中学到了这一点。您可以在模板标记中使用“as”关键字来使用模板中其他位置的调用结果。
例如:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
这在Django templatetag文档中提到,但仅参考循环。他们并不是说你可以在其他地方(任何地方?)使用它。
答案 26 :(得分:16)
django.views.generic.list_detail.object_list - 它提供所有逻辑和&amp;分页的模板变量(其中一个我写的那千万次现在的苦差事)。 Wrapping it允许您需要的任何逻辑。这个gem在我的“搜索结果”页面中为我节省了数小时的调试错误,并使视图代码更加清晰。
答案 27 :(得分:16)
PyCharm IDE是一个很好的代码,特别是调试环境,内置了对Django的支持。
答案 28 :(得分:14)
使用数据库迁移。使用South。
答案 29 :(得分:14)
使用xml_models创建使用XML REST API后端(而不是SQL后端)的Django模型。这在建模第三方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'
它还可以处理关系和集合。我们每天都在大量使用的生产代码中使用它,所以即使它是beta版,它也非常实用。它还有一组很好的存根,可以在测试中使用。
(免责声明:虽然我不是这个图书馆的作者,但我现在是一个提交者,做了一些小的提交)
答案 30 :(得分:13)
刚刚找到这个链接:http://lincolnloop.com/django-best-practices/#table-of-contents - “Django Best Practices”。
答案 31 :(得分:12)
如果您对模型进行更改
./manage.py dumpdata appname > appname_data.json
./manage.py reset appname
django-admin.py loaddata appname_data.json
答案 32 :(得分:12)
不是评估整个查询集来检查是否有任何结果,而是使用Django 1.2+中的.exists()和以前版本的.count()。
exists()和count()都按子句清除顺序,并从DB中检索单个整数。但是,exists()将始终返回1,其中count可以返回更高的值,在该值上将手动应用限制。在for(()中使用的has_result和在count()中用于好奇的get_count的来源。
由于它们都返回一个整数,因此没有模型实例化,在内存中加载模型属性,并且在数据库和应用程序之间没有传递大的TextField。
如果您已经评估了查询,.count()计算len(cached_result)和.exists()计算bool(cached_result)
效率不高 - 示例1
books = Books.objects.filter(author__last_name='Brown')
if books:
# Do something
效率不高 - 示例2
books = Books.objects.filter(author__last_name='Brown')
if len(books):
# Do something
高效 - 示例1
books = Books.objects.filter(author__last_name='Brown')
if books.count():
# Do something
高效 - 示例2
books = Books.objects.filter(author__last_name='Brown')
if books.exists():
# Do something
答案 33 :(得分:11)
我在Django网站的settings.py
中做的一件事是从/etc
中的文件加载数据库访问信息。这样,每台计算机的访问设置(数据库主机,端口,用户名,密码)可能不同,而密码等敏感信息不在我项目的存储库中。您可能希望以类似的方式限制对工作人员的访问,方法是使用不同的用户名进行连接。
您还可以通过环境变量传递数据库连接信息,甚至只传递配置文件的密钥或路径,并在settings.py
中处理它。
例如,以下是我如何提取数据库配置文件:
g = {}
dbSetup = {}
execfile(os.environ['DB_CONFIG'], g, dbSetup)
if 'databases' in dbSetup:
DATABASES = dbSetup['databases']
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
# ...
}
}
毋庸置疑,您需要确保除了数据库管理员和Django本身之外的任何用户都无法访问DB_CONFIG
中的文件。默认情况下应该将Django引用到开发人员自己的测试数据库。使用ast
模块而不是execfile
可能还有更好的解决方案,但我还没有研究过它。
我做的另一件事是使用单独的用户进行数据库管理任务与其他所有内容。在我的manage.py
中,我添加了以下序言:
# 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
/etc/django/db_regular.py
中的配置适用于只能使用SELECT,INSERT,UPDATE和DELETE访问Django数据库的用户,而/etc/django/db_admin.py
适用于具有这些权限的用户加上CREATE,DROP ,INDEX,ALTER和LOCK TABLES。 (migrate
命令来自South。)这给了我一些保护,免受Django代码在运行时弄乱我的模式,并且它限制了SQL注入攻击可能造成的破坏(尽管你仍然应该检查和过滤所有用户输入)。
(从我对another question的回答中复制)
答案 34 :(得分:11)
使用signals即时添加访问者方法。
我在django-photologue中看到了这种技术:对于添加的任何Size对象,post_init信号会将相应的方法添加到Image模型中。
如果您添加网站巨人,那么以巨大分辨率检索图片的方法将为image.get_giant_url()
。
通过从add_accessor_methods
信号中调用post_init
来生成方法:
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))
请参阅source code of photologue.models了解实际使用情况。
答案 35 :(得分:9)
不是在localhost上运行Django dev服务器,而是在适当的网络接口上运行它。例如:
python manage.py runserver 192.168.1.110:8000
或
python manage.py runserver 0.0.0.0:8000
然后,您不仅可以轻松使用Fiddler(http://www.fiddler2.com/fiddler2/)或其他工具(如HTTP调试器(http://www.httpdebugger.com/)来检查您的HTTP标头,还可以从您的其他计算机上访问您的开发网站局域网测试。
虽然开发服务器很小且相对安全,但请确保您受到防火墙的保护。
答案 36 :(得分:7)
在自定义视图装饰器中使用wraps
装饰器来保留视图的名称,模块和文档字符串。 E.g。
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
小心:如果作者尚未定义__call__
属性,则无法处理基于类的视图(具有__name__
方法定义的视图)。作为解决方法使用:
from django.utils.decorators import available_attrs
...
@wraps(fun, assigned=available_attrs(fun))
答案 37 :(得分:7)
Django Debug Toolbar非常棒。它实际上不是一个工具栏,它实际上会显示一个侧窗,它会告诉您有关您正在查看的页面的所有信息 - 数据库查询,发送到模板的上下文变量,信号等等。
答案 38 :(得分:6)
使用'apps'文件夹整理您的应用程序,而无需编辑PYTHONPATH
当我想组织这样的文件夹时,这很方便:
apps/
foo/
bar/
site/
settings.py
urls.py
不会覆盖PYTHONPATH或必须为每个导入添加应用,例如:
from apps.foo.model import *
from apps.bar.forms import *
在你的settings.py中添加
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/
看到了这个答案 39 :(得分:5)
在你的urlconf中使用reverse。
这是其中一个我不明白为什么它不是默认值的技巧。
这是我选择它的地方的链接: http://andr.in/2009/11/21/calling-reverse-in-django/
以下是代码段:
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') )
答案 40 :(得分:5)
在生产环境(settings.py)上自动设置'DEBUG'属性
import socket
if socket.gethostname() == 'productionserver.com':
DEBUG = False
else:
DEBUG = True
答案 41 :(得分:5)
Render form via django template instead of as_(ul|table|p)()
本文介绍了如何使用模板来呈现CusstomForms而不是as_p()
,as_table()
......
让它改变工作
from django import newforms as forms
至 from django import forms
from django.newforms.forms import BoundField
至 from django.forms.forms import BoundField
答案 42 :(得分:5)
使用 djangorecipe 管理您的项目
你要做的就是这个:
创建一个buildout.cfg,其中包含以下内容:
[buildout]
parts=django
[django]
recipe=djangorecipe
version=1.1.1
project=my_new_site
settings=development
python bootstrap.py
(如果您想使用分发,则为python bootstrap_dev.py
。./bin/buildout
就是这样。您现在应该有一个新的文件夹“my_new_site”,这是您的新django 1.1.1项目,在./bin中,您将找到django
- 脚本,它取代了正常安装中的manage.py.
有什么好处?假设您想在项目中使用django-comment-spamfighter之类的东西。您所要做的就是将buildout.cfg更改为以下内容:
[buildout]
parts=django
[django]
recipe=djangorecipe
version=1.1.1
project=my_new_site
settings=development
eggs=
django-comments-spamfighter==0.4
请注意,我所做的只是添加最后两行,即django-part也应该在版本0.4中使用django-comments-spamfighter包。下次运行./bin/buildout
时,buildout将下载该软件包并修改./bin/django以将其添加到PYTHONPATH。
djangorecipe也适合使用mod_wsgi部署项目。只需将wsgi=true
设置添加到buildout.cfg的django-part中,并在./bin文件夹中显示“django.wsgi”: - )
如果将test
选项设置为应用程序列表,djangorecipe将为您创建一个很好的包装器,它可以为项目中列出的应用程序运行所有测试。
如果您想在独立环境中开发单个应用程序以进行调试等,Jakob Kaplan-Moss有一个关于his blog的完整教程
答案 43 :(得分:4)
在init上更改Django表单字段属性
有时将额外的参数传递给Form类会很有用。
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]
答案 44 :(得分:4)
这是一种非常简单的方法,可以在python shell中再次导入另一个模型。
首先,安装IPython(如果你不使用IPython,你有什么问题?)。接下来,在django项目目录中创建一个python脚本ipythonrc.py,其中包含以下代码:
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文件”部分中:
execfile /path/to/project/ipythonrc.py
现在,每次启动IPython或运行./manage.py shell
时,您都可以导入所有模型并准备使用。无需再次导入另一个模型。
您还可以将您执行的任何其他代码放在ipythonrc.py文件中以节省时间。
答案 45 :(得分:2)
django_extensions
非常棒。
很少有./manage.py
个命令:
shell_plus
- 自动导入所有INSTALLED_APPS show_urls
- 打印项目runscript
- 在项目上下文中运行任何脚本(您可以使用模型和其他与Django相关的模块)答案 46 :(得分:2)
答案 47 :(得分:1)
为具有相同结构的旧表组创建动态模型:
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()
这假设您具有相同结构的旧表。您可以定义一个基本模型,而不是创建包装每个表的模型,并动态构造与特定表交互所需的类。
答案 48 :(得分:1)
派对有点晚了。但是Django Canvas最近问世,它应该在这里占有一席之地。
不要使用django-admin.py startproject
启动项目。相反,您可以使用Django Canvas之类的东西来帮助将空白项目与您需要的模块拼凑在一起。
你去那个网站,勾选一些选项,然后下载一个空白项目,这很简单。
它具有所有常见功能,例如南模式迁移和命令扩展,以及此处提到的许多其他最佳实践。此外,它有一个很棒的start.sh/shart.bat
脚本,可以安装python,virtualenv,pip,django以及从windows,osx或linux的新副本开始所需的任何内容。
答案 49 :(得分:1)
使用isapi-wsgi和django-pyodbc在Windows上使用IIS和SQL Server运行Django!
答案 50 :(得分:1)
使用异步任务。使用Celery
答案 51 :(得分:1)
如果您还没有,请阅读Unbreaking Django。它包含很多有关django陷阱的有用信息。
答案 52 :(得分:0)
将变量从视图传递到模板时,响应字典可能会变得单调乏味。我发现使用locals()
一次传递所有局部变量很好。
def show_thing(request, thing_id):
thing = Thing.objects.get(pk=thing_id)
return render_to_response('templates/things/show.html', locals())
(不是隐藏的功能本身,但在Python和/或Django新手时仍然有用。)
编辑:显然,明确而不是隐含,但这种方法在开发过程中会有所帮助。
答案 53 :(得分:0)
dir()&amp;提出ValueError()
为了在开发过程中调试/探索事物的状态,我使用以下技巧:
...
to_see = dir(inspect_this_thing)
to_see2 = inspect_this_thing.some_attribute
raise ValueError("Debugging")
...
当你正在处理没有特别好记录的django部分时,这是特别有用的(form.changed_fields是我最近使用过的那个)。
locals()。
不是为模板上下文写出每个变量,而是使用python builtin 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))
答案 54 :(得分:0)
Django没有应用程序设置,所以我自己做了app_settings.py检测。 在settings.py的底部,我添加了以下代码:
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()
它检测所有INSTALLED_APPS中的app_settings.py。它将读取app_settings文件的内容并将内联执行,而不是导入它。如果直接导入app_settings,将引发所有类型的Django导入错误(因为Django尚未初始化)。
所以我的app / app_settings.py看起来像这样:
MIDDLEWARE_CLASSES += (
'app.middleware.FancyMiddleware',
)
现在只需将应用程序添加到INSTALLED_APPS,而不是查找所有应用程序设置并将它们添加到settings.py(中间件,网址...)
注意:如果Django有一个附加额外设置的钩子会更好,所以可以在启动时(或在运行时)添加应用程序设置。