Відповіді:
Я просто почну з підказки від себе :)
Використовуйте os.path.dirname () у налаштуваннях.py, щоб уникнути жорстких кодів dirname.
Не встановлюйте жорсткий код у вашому 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"),
)
Кредити: Цю пораду я отримав із екранізації " Django From the Ground Up ".
j = lambda filename: os.path.join(PROJECT_DIR, filename)
. Тоді вам просто потрібно набрати j("static")
.
wontfix
рішення.
Встановіть Django Command Extensions та pygraphviz, а потім видайте таку команду, щоб отримати дійсно красиву візуалізацію моделі Django:
./manage.py graph_models -a -g -o my_project.png
Використовуйте декоратор джанго-дратівливого, 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 (наприклад, переадресація) призведе до короткого замикання декоратора і працювати так, як ви очікуєте.
Існує набір спеціальних тегів, які я використовую у всіх шаблонах свого сайту. Шукаючи способу його автоматичного завантаження (сушився, пам’ятаєте?), Я знайшов таке:
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'
).
Virtualenv + Python = збереження життя, якщо ви працюєте над декількома проектами Django і є ймовірність, що всі вони не залежать від однієї і тієї ж версії Django / програми.
virtualenv myNewEnv --no-site-packages
; . myNewEnv/bin/activate
; pip install django
; І це просто працює!
Не жорстко кодуйте свої URL-адреси!
Натомість використовуйте назви URL та reverse
функцію отримання самої URL-адреси.
Коли ви визначаєте відображення URL-адрес, вкажіть назви своїм URL-адресам.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Переконайтесь, що ім’я унікальне за URL-адресою.
Зазвичай у мене є послідовний формат "проект-додаток-перегляд", наприклад, "cbx-forum-thread" для подання потоку.
ОНОВЛЕННЯ (безсоромно вкравши додаток Айяза ):
Це ім'я можна використовувати в шаблонах з url
тегом .
url
тег ... Його позиція полягає в тому, що URL-адреси не повинні змінюватися в будь-якому випадку (якщо ви хочете бути дружніми до своїх користувачів).
{% url path.to.view.name arg1 arg2 %}
docs.djangoproject.com/en/dev/ref/templates/builtins/…
reverse
так, environment.filters['url'] = django.core.urlresolvers.reverse
і ви можете використовувати його у своїх шаблонах так: {{ 'view-name'|url(arg1, arg2)|e }}
("e" потрібно, щоб уникнути деяких символів для включення в HTML)
Використовуйте панель інструментів налагодження django . Наприклад, він дозволяє переглядати всі запити SQL, що виконуються під час перегляду, а також ви можете переглянути стек-трек для будь-якого з них.
Не пишіть власні сторінки для входу. Якщо ви використовуєте 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'),
)
Скажіть, у вас інша модель користувача, і ви хочете включити це у кожну відповідь. Замість цього:
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
автоматично включає ключ.
Я писав про це в блозі кілька місяців тому, тому я просто збираюся вирізати та вставляти:
З-під коробки Джанго подає кілька сигналів, які неймовірно корисні. Ви маєте можливість робити речі до і після збереження, ініціації, видалення або навіть під час обробки запиту. Тож давайте відійдемо від понять і продемонструємо, як вони використовуються. Скажіть, у нас є блог
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, щоб підключити функцію до моделі "Пост" та виконати її після її збереження.
Коли я починав, я не знав, що існує Пагінатор , переконайтесь, що ви знаєте про його існування !!
Використовуйте IPython, щоб перейти до вашого коду на будь-якому рівні та налагодити, використовуючи потужність IPython. Після встановлення IPython просто покладіть цей код туди, де ви хочете налагоджувати:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Потім оновіть сторінку, перейдіть до свого вікна runserver, і ви опинитеся в інтерактивному вікні IPython.
У мене встановлений фрагмент у TextMate, тому я просто набираю ipshell і клацніть на вкладці. Я не міг жити без цього.
ipdb
а потім просто наберітьipdb.set_trace()
Запустіть сервер розробки SMTP, який буде просто виводити все, що йому надіслано (якщо ви не хочете фактично встановлювати SMTP на свій сервер розробників.)
командний рядок:
python -m smtpd -n -c DebuggingServer localhost:1025
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
надрукує електронну пошту на manage.py
вихід.
З документації django-admin :
Якщо ви використовуєте оболонку Bash, подумайте про встановлення сценарію завершення баш Django, який знаходиться extras/django_bash_completion
в дистрибутиві Django. Це дозволяє завершити вкладку django-admin.py
та manage.py
команди, так що ви можете, наприклад, ...
django-admin.py
.sql
, а потім [TAB], щоб побачити всі доступні параметри, імена яких починаються з sql
../manage.py runserver_plus
Facilty , який поставляється з django_extensions воістину дивним.
Він створює розширену сторінку налагодження, яка, крім іншого, використовує налагоджувач Werkzeug для створення інтерактивних консолей налагодження для кожної точки стека (див. Скріншот). Він також надає дуже корисний метод налагодження зручності dump()
для відображення інформації про об'єкт / кадр.
Щоб встановити, ви можете використовувати pip:
pip install django_extensions
pip install Werkzeug
Потім додайте 'django_extensions'
до свого INSTALLED_APPS
кортежу settings.py
та запустіть сервер розробки з новим розширенням:
./manage.py runserver_plus
Це змінить спосіб налагодження.
Мені подобається використовувати налагоджувач pdb Python для налагодження проектів Django.
Це корисне посилання для того, як навчитися ним користуватися: http://www.ferg.org/papers/debugging_in_python.html
Намагаючись обмінюватися даними між Django та іншим додатком, request.raw_post_data
є хорошим другом. Використовуйте його для отримання та користувацької обробки, скажімо, XML-даних.
Документація: http://docs.djangoproject.com/en/dev/ref/request-response/
Використовуйте Jinja2 разом з Django.
Якщо ви вважаєте, що мова шаблону Django є надзвичайно обмежуючою (як я!), То вам не доведеться зациклюватися на ній. Django є гнучким, а мова шаблону слабко пов'язана з рештою системи, тому просто підключіть іншу мову шаблону і використовуйте його, щоб надати ваші http відповіді!
Я використовую Jinja2 , це майже як ввімкнена версія мови шаблону django, він використовує той самий синтаксис і дозволяє використовувати вирази, якщо заяви! більше не створювати спеціальні if-теги, такі як if_item_in_list
! ви можете просто сказати %{ if item in list %}
, або{% if object.field < 10 %}
.
Але це ще не все; У нього є багато інших функцій для полегшення створення шаблонів, тому я не можу перейти, хоча всі вони тут.
Додайте assert False
у код перегляду, щоб скинути інформацію про налагодження.
5 / 0
себе. Чому п’ять? Не маю уявлення.
Це додає до відповіді вище про імена URL-адрес Джанго та зворотну розсилку URL-адрес .
Імена URL-адрес також можна ефективно використовувати в шаблонах. Наприклад, для заданого шаблону URL:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
у шаблонах ви можете мати таке:
<a href="{% url project_team project.id %}">Team</a>
Оскільки "перегляди" Джанго мають бути лише дзвінками, які повертають 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),
)
Замість того, 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 в основному показують їх як ярлики для того, щоб навіть не було файлу view.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}
)
render
метод ярлика від Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
У мене недостатньо репутації, щоб відповісти на коментар, про який йдеться, але важливо зазначити, що якщо ви збираєтеся використовувати Jinja , він не підтримує символ "-" у назвах блоків шаблонів, у той час як Django це робить. Це спричинило мені чимало проблем і витрачало час, намагаючись відстежувати дуже незрозуміле повідомлення про помилку, яке воно створювало.
Додаток для веб-дизайну дуже корисний для початку дизайну вашого веб-сайту. Після імпортування ви можете додати це для створення зразкового тексту:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model
дає змогу отримати модель, не імпортуючи її.
Джеймс показує, наскільки це може бути зручно: "Поради щодо Джанго: Напишіть кращі теги шаблонів - Ітерація 4" .
Всім відомо, що існує сервер розробки, на якому можна запустити "management.py runserver", але чи знали ви, що існує перегляд розробки для обслуговування статичних файлів (CSS / JS / IMG)?
Новачки завжди спантеличені тим, що Джанго не має жодного способу подачі статичних файлів. Це тому, що команда розробників вважає, що це робота для веб-сервера в реальному житті.
Але розвиваючись, ви, можливо, не захочете налаштовувати 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/.
Звичайно, не використовуйте його у виробничих умовах.
Про це я дізнався з документації на ескізи сорлів . Ви можете використовувати ключові слова "як" у тегах шаблонів, щоб використовувати результати виклику в іншому місці вашого шаблону.
Наприклад:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Про це згадується, проходячи в документації з тегами шаблонів Django, але лише стосовно циклів. Вони не закликають, що ви також можете використовувати це деінде (де завгодно?).
django.views.generic.list_detail.object_list - Він надає всі змінні логіки та шаблону для розбиття на сторінки (одна з тих, що я написала-що-тисячу разів-зараз друкарі). Обгортання дозволяє використовувати будь-яку логіку, яка вам потрібна. Цей дорогоцінний камінь врятував мені багато годин налагодження помилок по черзі на моїх сторінках "Результати пошуку" та робить код перегляду чистішим у процесі.
PyCharm IDE - це приємне середовище для кодування та, особливо, налагодження, із вбудованою підтримкою Django.
Використовуйте xml_models для створення моделей Django, в яких використовується API XML REST API (замість 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>
А тепер у 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'
Він також може обробляти стосунки та колекції. Ми використовуємо його щодня у широко використовуваному виробничому коді, тому, хоча це бета-версія, вона дуже зручна. Він також має гарний набір заглушок, які ви можете використовувати у своїх тестах.
(Відмова: хоча я не автор цієї бібліотеки, я зараз є членом комітету, зробивши кілька незначних зобов'язань)