首页 文章

最喜欢的Django提示和功能?

提问于
浏览
308

受到“隐藏的......的特征”系列的启发,我很想知道你最喜欢的Django技巧或者你知道但鲜为人知但有用的功能 .

  • 请每个答案只包含一个提示 .

  • 添加Django版本要求(如果有) .

30 回答

  • 88

    使用IPython跳转到任何级别的代码并使用IPython的强大功能进行调试 . 一旦安装了IPython,只需将此代码放在要调试的任何位置:

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

    然后,刷新页面,转到runserver窗口,您将进入交互式IPython窗口 .

    我在TextMate中设置了一个代码段,所以我只需输入ipshell并点击tab . 没有它我就活不下去 .

  • 33

    运行开发SMTP服务器,只输出发送给它的任何内容(如果您不想实际安装SMTP)你的开发服务器 . )

    命令行:

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

    来自django-admin documentation

    如果您使用Bash shell,请考虑安装Django bash完成脚本,该脚本位于Django发行版的 extras/django_bash_completion 中 . 它启用 django-admin.pymanage.py 命令的制表符完成,因此您可以,例如......

    • 键入 django-admin.py .

    • 按[TAB]查看所有可用选项 .

    • 键入 sql ,然后键入[TAB],查看名称以 sql 开头的所有可用选项 .

  • 18

    我只想从自己的小贴士开始:)

    Use os.path.dirname() in settings.py to avoid hardcoded 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'得到了这个提示 .

  • 27

    安装Django Command Extensionspygraphviz,然后发出以下命令以获得非常漂亮的Django模型可视化:

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

    使用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(如重定向)将使装饰器短路并按预期工作 .

  • 47

    我在网站的模板上使用了一组自定义标签 . 正在寻找一种自动加载它的方法(干,记得吗?),我发现了以下内容:

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

    如果您将此项放在一个模块中,'s loaded by default (your main urlconf for instance), you' ll可以在任何模板中使用自定义标记模块中的标记和过滤器,而不使用 {% load custom_tag_module %} .

    传递给 template.add_to_builtins() 的参数可以是任何模块路径;您的自定义标记模块没有't have to live in a specific application. For example, it can also be a module in your project'的根目录(例如 'project.custom_tag_module' ) .

  • 19

    Virtualenv Python =生命保护程序,如果您正在处理多个Django项目,并且它们都可能不依赖于相同版本的Django /应用程序 .

  • 43

    不要硬编码您的网址!

    改为使用url namesreverse函数来获取URL本身 .

    定义URL映射时,请为URL指定名称 .

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

    确保每个URL的名称唯一 .

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

    UPDATE (无耻地偷窃ayaz's addition):

    此名称可以在url tag的模板中使用 .

  • 16

    使用django debug toolbar . 例如,它允许查看渲染视图时执行的所有SQL查询,您还可以查看其中任何一个的堆栈跟踪 .

  • 14

    不要编写自己的登录页面 . 如果您正在使用django.contrib.auth .

    真正的,肮脏的秘密是,如果你也使用django.contrib.admin,并且django.template.loaders.app_directories.load_template_source在你的模板加载器中, you can get your templates free too!

    # somewhere in urls.py
    urlpatterns += patterns('django.contrib.auth',
        (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
        (r'^accounts/logout/$','views.logout'),
    )
    
  • 40

    上下文处理器非常棒 .

    假设您有不同的用户模型,并且希望在每个响应中包含该模型 . 而不是这样做:

    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)
    

    因此,不知何故,您想要通知我们发布新帖子的许多博客ping服务之一,重建最新的帖子缓存,并发布有关它的推文 . 有了信号,你就可以完成所有这些操作而无需向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模型并在保存后执行它 .

  • 14

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

  • 19

    django_extensions附带的 ./manage.py runserver_plus facilty非常棒 .

    它创建了一个增强的调试页面,除其他外,它使用Werkzeug调试器为堆栈中的每个点创建交互式调试控制台(参见屏幕截图) . 它还提供了一个非常有用的方便调试方法 dump() ,用于显示有关对象/帧的信息 .

    enter image description here

    要安装,您可以使用pip:

    pip install django_extensions
    pip install Werkzeug
    

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

    ./manage.py runserver_plus
    

    这将改变您的调试方式 .

  • 35

    我喜欢使用Python调试器pdb来调试Django项目 .

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

  • 119

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

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

  • 57

    在视图代码中添加 assert False 以转储调试信息 .

  • 35

    与Django一起使用Jinja2 .

    如果你发现Django模板语言受到极大限制(比如我!)那么你就不必坚持下去了 . Django非常灵活,模板语言与系统的其他部分松散耦合,因此只需插入另一种模板语言并使用它来呈现您的http响应!

    我使用Jinja2,它几乎就像是django模板语言的加电版本,它使用相同的语法,并允许你在if语句中使用表达式!不再制作自定义的if-tags,例如 if_item_in_list !你可以简单地说 %{ if item in list %} ,或 {% if object.field < 10 %} .

    但那还不是全部;它有更多的功能来简化模板创建,我不能在这里完成所有这些功能 .

  • 82

    这增加了上面关于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>
    
  • 222

    由于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),
    )
    
  • 130

    而不是使用 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}
        )
    
  • 41

    重要的是要注意,如果你打算使用Jinja,它不支持模板块名称中的'-'字符,而Django则支持.1758651_字符 . 这给我带来了很多问题,并且浪费时间试图追踪它生成的非常模糊的错误消息 .

  • 97

    webdesign app在开始设计您的网站时非常有用 . 导入后,您可以添加此项以生成示例文本:

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

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

    詹姆斯表明它有多么方便:"Django tips: Write better template tags — Iteration 4 " .

  • 20

    大家都知道有一个可以用“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/上提供 .

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

  • 19

    我从sorl-thumbnails app的文档中学到了这一点 . 您可以在模板标记中使用"as"关键字来使用模板中其他位置的调用结果 .

    例如:

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

    这在Django templatetag文档中提到,但仅参考循环 . 他们并不是说你可以在其他地方(任何地方?)使用它 .

  • 37

    django.views.generic.list_detail.object_list - 它提供了分页的所有逻辑和模板变量(其中一个我已经写过的那一千次现在的苦差事) . Wrapping it允许您需要的任何逻辑 . 这个gem在我的"Search Results"页面中为我节省了数小时的调试错误,并使视图代码更加清晰 .

  • 80

    PyCharm IDE是一个很好的代码,特别是调试环境,内置了对Django的支持 .

  • 16

    使用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版,它也非常实用 . 它还有一组很好的存根,可以在测试中使用 .

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

  • 102

    使用数据库迁移 . 使用South .

相关问题