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


308

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

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

Ответы:


221

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

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

Не указывайте жесткий путь в вашем файле 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"),
)

Кредиты: я получил этот совет из фильма « Джанго с нуля ».


75
Вы не должны понижать голос людей, которые отвечают на их собственные вопросы. Это поощряется, даже если это предопределено.
Паоло Бергантино

19
Это такая хорошая идея, что мне все еще трудно понять, почему это не по умолчанию. Сколько людей тестируют и внедряют на одной машине?
SingleNegationElimination

19
Это избавляет вас от всегда типа os.path.join () , который получает раздражает довольно быстро: j = lambda filename: os.path.join(PROJECT_DIR, filename). Тогда вам просто нужно ввести j("static").
ср.

13
Если вы работаете в Windows, замените обратную косую черту: os.path.join (PROJECT_DIR, "templates"). Replace ('\\', '/')
Питер Мортенсен

7
Если вы действительно хотите исправить это в Django, оставьте комментарий к code.djangoproject.com/ticket/694 с просьбой, чтобы основные разработчики пересмотрели это wontfixрешение.
сорин

128

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

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

Хорошо, не удалось заставить pygraphviz правильно установить в Windows, но он все еще может скрыться из файла точек с помощью graphviz.
Monkut

Я люблю делиться модельными диаграммами с этим определенно +1
BozoJoe 19.10.10

Есть ли для этого опция svg?
Кейо

выходное изображение, похоже, обанкротилось
Брайан Виггинтон

119

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


4
@becomingGuru - это происходит автоматически.
Доминик Роджер

15
Это нормально, если вы не возвращаете некоторые HttpResponseRedirect () и несколько render_to_response (). Тогда перенаправления не удаются.
Мэтью Шинкель

17
Мне это не нравится «Явное лучше, чем неявное». Декоратор не сообщает, когда именно он собирается сделать render_to.
Тамас Селеи

2
@ Мэтью Шинкель: на самом деле он не портит перенаправления - если вы возвращаете объект HttpResponse, он просто передает его без изменения
Jiaaro

20
Я считаю , что этот подход теперь избыточно от Django 1.3 см django.shortcuts.render () docs.djangoproject.com/en/dev/topics/http/shortcuts/#render
Дольф

101

Есть набор пользовательских тегов, которые я использую по всем шаблонам моего сайта. Ища способ его автозагрузки (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').


@Steef, вы только что сэкономили мне массу времени / душевной боли / байтов, спасибо.
orokusaki

Действительно мило. Спасибо. Кроме того, хранилище пользовательских тегов было бы замечательно, чтобы поделиться вещами, не так ли?
Леандро Ардиссоне

Это здорово, пока кто-то другой не должен поддерживать ваш код. Подумайте: «принцип наименьшей магии»
Рич

96

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


15
Это ТОЛЬКО способ катиться!
постфутурист

3
Не могли бы вы добавить учебные ссылки для virtualenv с django?
BozoJoe 19.10.10

2
@BozoJoe: Сделайте это в вашем терминале: virtualenv myNewEnv --no-site-packages; . myNewEnv/bin/activate; pip install django; И это просто работает!
SingleNegationElimination

87

Не кодируйте свои URL жестко!

Вместо этого используйте имена URL и reverseфункцию, чтобы получить сам URL.

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

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

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

У меня обычно есть согласованный формат "project-appplication-view", например "cbx-forum-thread" для представления потока.

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

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


1
Я согласен на 100% по этому вопросу. Я начал использовать жестко запрограммированные URL-адреса, и это укусило меня в проект, когда я немного изменил формат URL-адреса, чтобы учесть некоторые изменения. Я нашел время, чтобы вернуться и копаться во всем и заменить жестко закодированные URL-адреса. Моя единственная большая жалоба заключается в том, что ошибки тегов URL убивают всю страницу, а жестко запрограммированные только портят отдельные ссылки.
Рикри

21
Это не должно быть скрытой функцией, это лучшая практика и единственный способ летать.
Skylar Saveland

1
@skyl Это вряд ли "единственный способ летать". Я был на спринте в Django, и Адриан Головати (один из создателей Django) сказал, что он даже не использует urlтег ... Его позиция такова, что URL-адреса не должны меняться в любом случае (если вы хотите быть дружелюбными к вашему пользователей).
ТМ.

вы также можете использовать это в шаблонах, как в {% url path.to.view.name arg1 arg2 %} docs.djangoproject.com/en/dev/ref/templates/builtins/…
SingleNegationElimination

Если вы используете jinja2, просто добавьте reverseвот так, environment.filters['url'] = django.core.urlresolvers.reverseи вы можете использовать его в своих шаблонах примерно так: {{ 'view-name'|url(arg1, arg2)|e }}(«e» необходимо для экранирования некоторых символов для включения в HTML)
SingleNegationElimination


79

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

1
Прохладно! Я не знал, что мы можем повторно использовать страницу входа администратора. Спасибо!
Джошуа Партоги

66

Контекстные процессоры потрясающие.

Скажем, у вас другая модель пользователя, и вы хотите включить ее в каждый ответ. Вместо этого:

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)

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


4
Сигналы Django являются обязательной функцией для меня в наши дни при сравнении веб-фреймворков. Скажем, написание слабо связанного форума, который может прослушивать обновления, скажем, от модуля «подпись», но на самом деле не требует, чтобы этот модуль работал, и который также может работать с совместимыми модулями, реализующими ту же функцию. Я не знаю, почему сигналы не так известны и популярны.
Ли Б

Сигналы очень важны, чтобы избежать жесткой связи и путаницы кода в целом, если мы используем несколько многократно используемых приложений в нашем проекте. Вы предоставили отличный пример слабой связи приложений django, +1 за это.
Лукаш Коржибски

Вы знаете, являются ли сигналы асинхронными?
Кедар

«Скажем, у вас другая модель пользователя, и вы хотите включить ее в каждый ответ». - Поместите пользователя в сессию . Это спасает вас от попадания в базу данных для каждого запроса.
jammon

Звонки сигналов являются синхронными. На мой взгляд, какой-то асинхронный механизм работы больше подходит, например, для публикации в Twitter / Facebook / и т. Д. (Т.е. - rabbitmq), поэтому пользователи нашего веб-сайта не зависают по запросу.
Горский

58

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


2
: D это же для меня! Я провел дни на нумерацию страниц!
Викингосегундо

46

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

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

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

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


22
Лучше установить, ipdbа затем просто набратьipdb.set_trace()
Томаш Зелиньски

Или используйте отладчик Eclipse / PyDev. :-)
jMyles

3
импорт ipdb; ipdb.set_trace () FTW!
Хассек

43

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

командная строка:

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

12
Вы можете использовать консоль и архивировать почтовые серверы в django 1.2 для той же цели
Дмитрий Шевченко

выдающийся! идеально подходит для регистрации! +1
BozoJoe

3
Альтернатива в Django 1.2 с настройками: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' .. которая распечатает письмо на manage.pyвыходе.
vdboor

41

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

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

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

1
Это более полезно, чем я ожидал. Спасибо!
Jeeyoung Ким

Это по умолчанию в более новых Ubuntu по крайней мере. :-) Я был поражен, когда он впервые появился из ниоткуда.
Одино - Велмонт

40

./manage.py runserver_plusFacilty , который поставляется с django_extensions поистине удивительным.

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

введите описание изображения здесь

Для установки вы можете использовать pip:

pip install django_extensions
pip install Werkzeug

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

./manage.py runserver_plus

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


37

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

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


13
Это находка. Чтобы дать немного больше информации, просто добавьте это: «import pdb; pdb.set_trace ()» в любой строке вашего кода. Обновите свою страницу. Это будет висеть. Теперь перейдите в окно терминала, где вы запускаете сервер разработки. Теперь это должна быть интерактивная оболочка, в которой вы можете получить доступ ко всем переменным в том виде, в каком они находятся в той точке кода, куда вы вставили код отладки.
priestc

37

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

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


5
Вот как ты это делаешь. Спасибо, +1
SingleNegationElimination

36

Используйте Jinja2 вместе с Джанго.

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

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

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


Я также использую и наслаждаюсь Jinja2, но обнаружил, что есть некоторые связи с приложениями «contrib». В частности, инструмент администратора довольно сильно привязан к шаблонам Django. Кроме того, мне пришлось воссоздать декораторы входа в contrib.auth, чтобы быть дружелюбным к Jinja2, но не слишком сложно.
Джо Холлоуэй

24
Не заменяйте систему шаблонов на jinja2, просто «добавьте» ее, не удаляйте шаблоны django. Используйте Jinja2 для собственных представлений, и пусть интерфейс администратора продолжает использовать язык шаблонов django.
hasen

4
Я согласен с этим. Ограниченный синтаксис Django в большинстве случаев терпим, но когда вы приступаете к созданию пользовательских тегов и выясняете, насколько это сложно, Jinja2 - глоток свежего воздуха
SingleNegationElimination

Кроме того, если вы хотите выполнять какие-либо метапрограммирования на шаблонном источнике, Jinja2 гораздо более приятен, поскольку вы можете напрямую получить доступ к AST анализируемых шаблонов. Прогулка по AST делает такие задачи, как поиск шаблонов, расширяющих базовый шаблон, или перечисление несвязанных переменных в исходном блоке шаблона, почти тривиально легко.
rcoder

5
К счастью, в Django 1.2 тег IF гораздо умнее
Nixarn

35

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


4
Я думаю, что Утверждение Ложь является более интуитивным = D
Jiaaro

13
если вы запускаете свой проект на сервере разработки django, используйте модуль pdb для python. Это гораздо более мощный способ отладки: import pdb; pdb.stack_trace ()
mazelife

pdb очень полезен, у вас, скорее всего, будет тайм-аут соединения, если вы не очень быстро отлаживаете.
Стивен Полгер

4
Я всегда использую 5 / 0себя. Почему пять? Без понятия.
Джейсон Смит

@StephenPaulger действительно? Мой браузер (firefox / w firebug), кажется, готов подождать несколько минут ответа, пока я отлаживаю.
ТМ.

34

Это добавляет к ответу выше об именах 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>

27

Поскольку «представления» 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),
)

2
FWIW, авторы django фактически используют представления на основе классов в нескольких местах, например, contrib.formtools: code.djangoproject.com/browser/django/trunk/django/contrib/…
mazelife

3
Если вы добавите метод вызова, вы можете создать класс с именем RestfulResource и затем указать свой urls.py на экземпляры.
Стивен Полгер

1
Новые (Django 1.3?) Общие представления основаны на классах.
Горский

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}
    )

Сохраните еще больше LOC с помощью декоратора @render_to, доступного в django-раздражающем. bitbucket.org/offline/django-annoying
бездарно

6
..или использовать новый renderметод ярлыков из Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
gorsky

20

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


Одно примечание, которое может или не может быть применимо к "непонятным сообщениям об ошибках от jinja". Обязательно установите TEMPLATE_DEBUG = False в settings.py. По какой-то причине это даст вам значимые ошибки из шаблонов Jinja.
Карл Дж

19

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

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

4
К вашему сведению, для любого, кто использует Jinja2 вместо шаблонов Django, вы можете сделать: {{lipsum (5)}}
Джо Холлоуэй,

19

django.db.models.get_model позволяет вам получить модель, не импортируя ее.

Джеймс показывает, насколько это удобно: «Советы по Django: лучше пишите теги шаблонов - Итерация 4» .


Приятно: O! И здесь я делал ленивый импорт всякий раз, когда у меня были циклические зависимости.
Филипп Дупанович

19

Все знают, что есть сервер разработки, который вы можете запустить с помощью «manage.py runserver», но знаете ли вы, что существует представление разработки для обслуживания статических файлов (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/.

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


6
Я использую это в режиме разработки, и просто чтобы убедиться, что я не забуду отключить это в рабочей среде, я оборачиваю это правило URL только в DEBUG только условно.
sghael

18

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

Например:

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

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


7
Если ключевое слово as можно использовать с шаблоном-тегом, зависит от этого конкретного тега. Он определяется не самим django, а отдельными тегами, в зависимости от их значения. Загляните в упомянутый URL-тег, чтобы увидеть, как используется «как»: code.djangoproject.com/browser/django/trunk/django/template/…
vikingosegundo

16

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


1
Вы можете найти новую версию главы книги об общих взглядах на djangobook.com/en/2.0/chapter11 . Тот, что в комментарии, относится к версии книги Django до 1.0 (книга Django 1.0)
Эстебан Кубер


14

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

XML из API:

<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>

А теперь в питоне:

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'

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

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


интересный проект, так держать!
Сергей Головченко

Спасибо, это очень удобно :-)
Godswearhats

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.