Любимые советы и возможности Django?

Вдохновленный серией вопросов "Скрытые черты...", мне любопытно узнать о ваших любимых советах Django или менее известных, но полезных функциях, о которых вы знаете.

  • Пожалуйста, укажите только один отзыв для каждого ответа.
  • Добавьте требования к версии Django, если они есть.

Ответы

Ответ 1

Я собираюсь начать с подсказки от себя:)

Используйте os.path.dirname() в settings.py, чтобы избежать жестких кодировок dirnames.

Не указывайте путь hardcode в параметрах settings.py, если вы хотите запустить проект в разных местах. Используйте следующий код в settings.py, если ваши шаблоны и статические файлы находятся в каталоге проекта Django:

# 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"),
)

Кредиты: я получил этот совет от screencast 'Django From the Ground Up'.

Ответ 2

Установите Django Command Extensions и pygraphviz и затем выполните следующую команду, чтобы получить действительно приятную визуализацию модели Django:

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

Ответ 3

Используйте django-annoying render_to decorator вместо 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 (например, перенаправление) приведет к короткому замыканию декоратора и работе так, как вы ожидаете.

Ответ 4

Есть набор пользовательских тегов, которые я использую по всем шаблонам своего сайта. Ищете способ автозагрузки (DRY, помните?), Я нашел следующее:

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

Ответ 5

Virtualenv + Python = спасатель жизни, если вы работаете над несколькими проектами Django, и есть вероятность, что все они не зависят от той же версии приложения Django/.

Ответ 6

Не перекодируйте URL-адреса!

Используйте имена URL, а reverse для получения самого URL.

Когда вы определяете свои сопоставления URL-адресов, укажите имена для своих URL-адресов.

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

Убедитесь, что имя уникально для каждого URL.

Я обычно имею согласованный формат "представление проекта-приложения", например. "cbx-forum-thread" для представления потока.

ОБНОВЛЕНИЕ (бесстыдно украсть дополнение ayaz):

Это имя можно использовать в шаблонах с тегом url.

Ответ 7

Используйте панель инструментов отладки django. Например, он позволяет просматривать все SQL-запросы, выполняемые во время рендеринга, и вы также можете просматривать stacktrace для любого из них.

Ответ 8

Не записывайте свои собственные страницы входа. Если вы используете 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'),
)

Ответ 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))

Контекстные процессы дают вам возможность передавать любую переменную в вашу шаблоны. Обычно я помещаю мой в '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.

Также signals win.

Я написал сообщение в блоге об этом несколько месяцев назад, поэтому я просто собираюсь вырезать и вставить:

Из коробки 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)

Итак, так или иначе вы хотите уведомить одного из многих блогов услуги weve создали новую должность, перестроят самые последние кеши сообщений и твит. Хорошо с сигналами, которые у вас есть способность делать все это без необходимости добавлять методы для класса 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 и выполнить его после его сохранения.

Ответ 10

Когда я начинал, я не знал, что существует Paginator, убедитесь, что вы знаете о его существовании!!

Ответ 11

Используйте IPython, чтобы перейти на ваш код на любом уровне и отлаживать с использованием мощности IPython. После того, как вы установили IPython, просто поместите этот код туда, куда вы хотите отлаживать:

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

Затем обновите страницу, перейдите в окно вашего запуска и вы будете в интерактивном окне IPython.

У меня есть фрагмент, созданный в TextMate, поэтому я просто набираю ipshell и нажимаю вкладку. Я не мог жить без него.

Ответ 12

Запустите SMTP-сервер разработки, который просто выведет все, что ему отправлено (если вы не хотите фактически устанавливать SMTP на своем dev-сервере.)

:

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

Ответ 13

Из документация django-admin:

Если вы используете оболочку Bash, рассмотрите возможность установки завершения Django Bash script, который находится в extras/django_bash_completion в дистрибутиве Django. Он позволяет выполнять табуляцию команд django-admin.py и manage.py, поэтому вы можете, например...

  • Введите django-admin.py.
  • Нажмите [TAB], чтобы просмотреть все доступные параметры.
  • Введите sql, затем [TAB], чтобы просмотреть все доступные параметры, чьи имена начинаются с sql.

Ответ 14

Функция ./manage.py runserver_plus, которая поставляется с django_extensions, действительно потрясающая.

Он создает расширенную страницу отладки, которая, помимо прочего, использует отладчик Werkzeug для создания интерактивных консолей отладки для каждой точки в стеке (см. снимок экрана). Он также предоставляет очень полезный метод удобной отладки dump() для отображения информации об объекте/кадре.

enter image description here

Чтобы установить, вы можете использовать pip:

pip install django_extensions
pip install Werkzeug

Затем добавьте 'django_extensions' в тэг INSTALLED_APPS в settings.py и запустите сервер разработки с новым расширением:

./manage.py runserver_plus

Это изменит способ отладки.

Ответ 15

Мне нравится использовать pdon debugger pdb для отладки проектов Django.

Это полезная ссылка для изучения того, как ее использовать: http://www.ferg.org/papers/debugging_in_python.html

Ответ 16

При попытке обмена данными между Django и другим приложением request.raw_post_data является хорошим другом. Используйте его для получения и пользовательского процесса, скажем, данных XML.

Документация: http://docs.djangoproject.com/en/dev/ref/request-response/

Ответ 17

Используйте Jinja2 рядом с Django.

Если вы находите язык шаблона Django чрезвычайно ограниченным (например, я!), вам не нужно зацикливаться на нем. Django является гибким, а язык шаблонов слабо связан с остальной частью системы, поэтому просто подключайте другой язык шаблона и используйте его для отображения ваших ответов на http!

Я использую Jinja2, это почти похоже на включенную версию языка шаблонов django, он использует тот же синтаксис и позволяет вам использовать выражения в операторах if! больше не создавать пользовательские теги if, такие как if_item_in_list! вы можете просто сказать %{ if item in list %} или {% if object.field < 10 %}.

Но это не все; у него есть еще много возможностей для облегчения создания шаблонов, которые я не могу выполнить, хотя все они здесь.

Ответ 18

Добавьте assert False в свой код просмотра для вывода информации об отладке.

Ответ 19

Это добавляет ответ выше о именах URL-адресов Django и обратном URL-адресе.

Имена URL также могут быть эффективно использованы в шаблонах. Например, для заданного шаблона URL:

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

у вас могут быть следующие шаблоны:

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

Ответ 20

Поскольку Django "представления" должны быть только вызывающими, которые возвращают HttpResponse, вы можете легко создавать представления на основе классов, такие как в 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),
)

Ответ 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}
    )

Ответ 22

У меня недостаточно репутации для ответа на комментарий, но важно отметить, что если вы собираетесь использовать Jinja, он НЕ поддерживает символ "-" в именах блоков шаблонов, в то время как Django делает это. Это вызвало у меня много проблем и потрачено время, пытаясь отследить очень неясное сообщение об ошибке, которое оно сгенерировало.

Ответ 24

приложение для веб-дизайна очень полезно при создании вашего сайта. После импорта вы можете добавить это, чтобы сгенерировать образец текста:

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

Ответ 25

Всем известно, что есть сервер разработки, который вы можете запускать с помощью "manage.py runningerver", но знаете ли вы, что существует также представление для обслуживания статических файлов (CSS/JS/IMG)?

Новички всегда недоумевают, потому что Django не имеет возможности обслуживать статические файлы. Это объясняется тем, что команда разработчиков считает, что это работа для веб-сервера реальной жизни.

Но при разработке вы можете не захотеть настроить 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/.

Конечно, не используйте его в рабочей среде.

Ответ 26

Я узнал об этом из документации для sorl-thumbnails. Вы можете использовать ключевое слово "как" в тегах шаблонов, чтобы использовать результаты вызова в другом месте вашего шаблона.

Например:

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

Об этом упоминается в документации Django templatetag, но только в отношении циклов. Они не называют, что вы можете использовать это в другом месте (где угодно?).

Ответ 27

django.views.generic.list_detail.object_list - Он предоставляет все логические и шаблонные переменные для разбивки на страницы (один из тех, ve-written-that-a-тысяч раз-теперь тяжелые). Обертка позволяет использовать любую логику. Этот жемчуг спас меня много часов отладки по отдельности на моих страницах "Результаты поиска" и делает код просмотра более чистым в этом процессе.

Ответ 28

PyCharm IDE - хорошая среда для кодирования и особенно отладки со встроенной поддержкой Django.

Ответ 29

Используйте xml_models для создания моделей Django, которые используют бэкэнд API REST API (вместо SQL-кода). Это очень полезно, особенно при моделировании сторонних API-интерфейсов - вы получаете все тот же синтаксис QuerySet, к которому вы привыкли. Вы можете установить его из PyPI.

XML из API:

<profile id=4>
    <email>[email protected]</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 '[email protected]'

Он также может обрабатывать отношения и коллекции. Мы используем его каждый день в сильно используемом коде производства, поэтому, хотя он бета-версия очень удобна. Он также имеет хороший набор заглушек, которые вы можете использовать в своих тестах.

(Отказ от ответственности: пока я не являюсь автором этой библиотеки, теперь я являюсь коммиттером, совершив несколько мелких коммитов)

Ответ 30

Использовать миграцию базы данных. Используйте South.