Odpowiedzi:
Zacznę od napiwku od siebie :)
Użyj os.path.dirname () w settings.py, aby uniknąć zakodowanych nazw plików.
Nie wpisuj ścieżki kodu w pliku settings.py, jeśli chcesz uruchomić projekt w różnych lokalizacjach. Użyj następującego kodu w pliku settings.py, jeśli szablony i pliki statyczne znajdują się w katalogu projektu 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"),
)
Kredyty: Mam tę wskazówkę z screencastu „ Django From the Ground Up ”.
j = lambda filename: os.path.join(PROJECT_DIR, filename)
. Następnie wystarczy wpisać j("static")
.
wontfix
decyzji.
Zainstaluj rozszerzenia Django Command i pygraphviz, a następnie wydaj następujące polecenie, aby uzyskać naprawdę ładną wizualizację modelu Django:
./manage.py graph_models -a -g -o my_project.png
Zamiast tego użyj dekoratora django-irytującego .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))
Zredagowano, aby zwrócić uwagę, że zwracanie odpowiedzi HttpResponse (takiej jak przekierowanie) spowoduje zwarcie dekoratora i będzie działać zgodnie z oczekiwaniami.
Istnieje zestaw niestandardowych tagów, których używam we wszystkich szablonach mojej witryny. Szukając sposobu na automatyczne załadowanie (DRY, pamiętasz?), Znalazłem:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
Jeśli umieścisz to w module, który jest domyślnie ładowany (na przykład głównym urlconf), będziesz mieć tagi i filtry z niestandardowego modułu tagów dostępne w dowolnym szablonie, bez użycia {% load custom_tag_module %}
.
Argumentem przekazywanym do template.add_to_builtins()
może być dowolna ścieżka modułu; moduł niestandardowego znacznika nie musi znajdować się w określonej aplikacji. Może to być na przykład moduł w katalogu głównym projektu (np. 'project.custom_tag_module'
).
Virtualenv + Python = oszczędzanie życia, jeśli pracujesz nad wieloma projektami Django i istnieje możliwość, że nie wszystkie będą zależały od tej samej wersji Django / aplikacji.
virtualenv myNewEnv --no-site-packages
; . myNewEnv/bin/activate
; pip install django
; I to po prostu działa!
Nie koduj na stałe swoich adresów URL!
Zamiast tego użyj nazwreverse
adresów URL i funkcji, aby uzyskać sam adres URL.
Podczas definiowania odwzorowań adresów URL podaj nazwy swoich adresów URL.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Upewnij się, że nazwa jest unikalna dla każdego adresu URL.
Zwykle mam spójny format „projektu-aplikacji-widoku”, np. „Cbx-forum-thread” dla widoku wątku.
AKTUALIZACJA (bezwstydnie kradnie dodatek Ajaza ):
Tej nazwy można używać w szablonach ze url
znacznikiem .
url
tagu ... Jego postawa jest taka, że adresy URL i tak nie powinny się zmieniać (jeśli chcesz być przyjazny dla twojego użytkownicy).
{% url path.to.view.name arg1 arg2 %}
docs.djangoproject.com/en/dev/ref/templates/builtins/…
reverse
ten sposób environment.filters['url'] = django.core.urlresolvers.reverse
i możesz użyć go w swoich szablonach w następujący sposób: {{ 'view-name'|url(arg1, arg2)|e }}
(„e” jest potrzebne, aby uciec przed niektórymi znakami w celu włączenia do HTML)
Użyj paska narzędzi debugowania django . Na przykład umożliwia przeglądanie wszystkich zapytań SQL wykonanych podczas renderowania widoku, a także przeglądanie stosu dla każdego z nich.
Nie pisz własnych stron logowania. Jeśli używasz django.contrib.auth.
Prawdziwy, brudny sekret polega na tym, że jeśli używasz również django.contrib.admin, a django.template.loaders.app_directories.load_template_source znajduje się w modułach ładujących szablony, możesz również pobrać szablony za darmo!
# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
(r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
(r'^accounts/logout/$','views.logout'),
)
Załóżmy, że masz inny model użytkownika i chcesz go uwzględnić w każdej odpowiedzi. Zamiast tego:
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))
Procesy kontekstowe umożliwiają przekazanie dowolnej zmiennej do szablonów. Zazwyczaj umieszczam mój w '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='')
W swoim settings.py
dodaj następujący wiersz do swojegoTEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
Teraz za każdym razem, gdy jest wysyłane żądanie, my_user
automatycznie dołącza klucz.
Kilka miesięcy temu napisałem o tym na blogu, więc zamierzam po prostu wyciąć i wkleić:
Po wyjęciu z pudełka Django daje kilka sygnałów, które są niezwykle przydatne. Masz możliwość robienia rzeczy przed i po zapisywaniu, inicjowaniu, usuwaniu, a nawet podczas przetwarzania żądania. Odejdźmy więc od koncepcji i pokażmy, jak są one używane. Powiedzmy, że mamy bloga
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)
Więc w jakiś sposób chcesz powiadomić jedną z wielu usług pingowania blogów, o której napisaliśmy nowy post, odbudować pamięć podręczną najnowszych postów i opublikować tweeta. Cóż, z sygnałami możesz to wszystko zrobić bez konieczności dodawania jakichkolwiek metod do klasy 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)
Proszę bardzo, definiując tę funkcję i używając sygnału post_init, aby połączyć funkcję z modelem Post i wykonać ją po jej zapisaniu.
Kiedy zaczynałem, nie wiedziałem, że istnieje Paginator , upewnij się, że wiesz o jego istnieniu !!
Użyj IPython, aby wskoczyć do kodu na dowolnym poziomie i debugować przy użyciu mocy IPython. Po zainstalowaniu IPython umieść ten kod w miejscu, w którym chcesz debugować:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Następnie odśwież stronę, przejdź do okna runserver, a znajdziesz się w interaktywnym oknie IPython.
Mam fragment kodu skonfigurowany w TextMate, więc po prostu wpisuję ipshell i wciskam tab. Nie mogłem bez tego żyć.
ipdb
a następnie wpiszipdb.set_trace()
Uruchom programistyczny serwer SMTP, który po prostu wyśle wszystko, co zostanie do niego wysłane (jeśli nie chcesz tak naprawdę instalować SMTP na serwerze programisty).
wiersz poleceń:
python -m smtpd -n -c DebuggingServer localhost:1025
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
..tak wydrukuje wiadomość e-mail na manage.py
wyjściu.
Z dokumentacji django-admin :
Jeśli używasz powłoki Bash, rozważ zainstalowanie skryptu ukończenia bash Django, który znajduje się w extras/django_bash_completion
dystrybucji Django. Umożliwia uzupełnianie tabulatorów django-admin.py
i manage.py
poleceń, dzięki czemu można na przykład ...
django-admin.py
.sql
, a następnie [TAB], aby zobaczyć wszystkie dostępne opcje, których nazwy zaczynają się sql
../manage.py runserver_plus
Facilty która pochodzi z django_extensions jest naprawdę niesamowite.
Tworzy ulepszoną stronę debugowania, która między innymi używa debugera Werkzeug do tworzenia interaktywnych konsol debugowania dla każdego punktu na stosie (patrz zrzut ekranu). Zapewnia również bardzo przydatną wygodną metodę debugowania dump()
do wyświetlania informacji o obiekcie / ramce.
Aby zainstalować, możesz użyć pip:
pip install django_extensions
pip install Werkzeug
Następnie dodaj 'django_extensions'
do INSTALLED_APPS
krotki settings.py
i uruchom serwer programistyczny z nowym rozszerzeniem:
./manage.py runserver_plus
Zmieni to sposób debugowania.
Lubię używać debugera pdb Python do debugowania projektów Django.
To jest przydatny link do nauki korzystania z niego: http://www.ferg.org/papers/debugging_in_python.html
Podczas próby wymiany danych między Django a inną aplikacją request.raw_post_data
jest dobrym przyjacielem. Użyj go do odbierania i przetwarzania danych, powiedzmy, danych XML.
Dokumentacja: http://docs.djangoproject.com/en/dev/ref/request-response/
Użyj Jinja2 wraz z Django.
Jeśli uznasz, że język szablonów Django jest bardzo ograniczający (jak ja!), Nie musisz się z tym utknąć. Django jest elastyczny, a język szablonów jest luźno powiązany z resztą systemu, więc po prostu podłącz inny język szablonów i użyj go do renderowania odpowiedzi http!
Używam Jinja2 , jest to prawie jak ulepszona wersja języka szablonów django, używa tej samej składni i pozwala używać wyrażeń w instrukcjach if! nie trzeba tworzyć niestandardowych tagów if, takich jak if_item_in_list
! możesz po prostu powiedzieć %{ if item in list %}
, lub {% if object.field < 10 %}
.
Ale to nie wszystko; ma wiele innych funkcji ułatwiających tworzenie szablonów, których nie mogę przejść przez wszystkie tutaj.
Dodaj assert False
kod widoku, aby zrzucić informacje debugowania.
5 / 0
siebie. Dlaczego pięć? Brak pomysłu.
To dodaje do powyższej odpowiedzi dotyczącej nazw adresów URL Django i odwrotnego wysyłania adresów URL .
Nazw adresów URL można również skutecznie używać w szablonach. Na przykład dla danego wzorca adresu URL:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
możesz mieć następujące szablony:
<a href="{% url project_team project.id %}">Team</a>
Ponieważ „widoki” Django muszą być tylko wywoływalne, które zwracają odpowiedź HttpResponse, możesz łatwo tworzyć widoki oparte na klasach, takie jak te w Ruby on Rails i innych frameworkach.
Istnieje kilka sposobów tworzenia widoków opartych na klasach, oto moje ulubione:
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
W widoku podstawowym możesz dodać różnego rodzaju inne rzeczy, takie jak warunkowe przetwarzanie żądań i autoryzacja.
Po skonfigurowaniu widoków adres URL strony będzie wyglądał mniej więcej tak:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('',
(r'^restview/', MyRestView.dispatch),
)
Zamiast używać render_to_response
do wiązania kontekstu z szablonem i renderowania go (co zwykle pokazują dokumenty Django), użyj widoku ogólnego direct_to_template
. Robi to samo, co render_to_response
robi, ale automatycznie dodaje RequestContext do kontekstu szablonu, domyślnie pozwalając na użycie procesorów kontekstowych. Możesz to zrobić ręcznie za pomocą render_to_response
, ale po co? To tylko kolejny krok do zapamiętania i kolejny LOC. Oprócz korzystania z procesorów kontekstowych posiadanie RequestContext w szablonie pozwala na wykonywanie następujących czynności:
<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a>
co jest bardzo przydatne. W rzeczywistości +1 ogólnie za ogólne widoki. Dokumenty Django pokazują je głównie jako skróty, nawet w przypadku braku pliku views.py dla prostych aplikacji, ale można ich również używać w ramach własnych funkcji widoku:
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
metody skrótu z Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
Nie mam wystarczającej reputacji, aby odpowiedzieć na dany komentarz, ale ważne jest, aby pamiętać, że jeśli zamierzasz użyć Jinja , NIE obsługuje on znaku „-” w nazwach bloków szablonów, podczas gdy Django to robi. Spowodowało to wiele problemów i zmarnowałem czas, próbując wyśledzić bardzo niejasny komunikat o błędzie, który wygenerował.
Aplikacja webdesign jest bardzo przydatna na początku projektowania witryny. Po zaimportowaniu możesz dodać to, aby wygenerować przykładowy tekst:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model
pozwala odzyskać model bez importowania go.
James pokazuje, jak może być przydatny: „Wskazówki Django: Napisz lepsze tagi szablonów - Iteracja 4” .
Wszyscy wiedzą, że istnieje serwer programistyczny, który można uruchomić za pomocą „manage.py runserver”, ale czy wiesz, że istnieje również widok programistyczny do obsługi plików statycznych (CSS / JS / IMG)?
Nowicjusze są zawsze zdziwieni, ponieważ Django nie oferuje żadnego sposobu obsługi plików statycznych. Jest tak, ponieważ zespół deweloperów uważa, że jest to praca dla prawdziwego serwera WWW.
Ale podczas programowania możesz nie chcieć konfigurować Apache + mod_wisgi, jest ciężki. Następnie możesz po prostu dodać do urls.py:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
Twój CSS / JS / IMG będzie dostępny na stronie www.yoursite.com/site_media/.
Oczywiście nie używaj go w środowisku produkcyjnym.
Nauczyłem się tego z dokumentacji aplikacji sorl-thumbnails . Możesz użyć słowa kluczowego „as” w tagach szablonów, aby użyć wyników połączenia w innym miejscu w szablonie.
Na przykład:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Zostało to wspomniane w dokumentacji szablonów Django, ale tylko w odniesieniu do pętli. Nie wzywają, że możesz użyć tego również w innym miejscu (gdziekolwiek?).
django.views.generic.list_detail.object_list - Zapewnia wszystkie zmienne logiczne i szablony do paginacji (jedna z tych kryminałów, które napisałem tysiące razy). Owijanie pozwala na dowolną logikę, której potrzebujesz. Ten klejnot zaoszczędził mi wiele godzin debugowania błędów po kolei na moich stronach „Wyniki wyszukiwania” i sprawia, że kod widoku jest czystszy.
PyCharm IDE to ładne środowisko do kodowania, a zwłaszcza debugowania, z wbudowaną obsługą Django.
Użyj xml_models, aby utworzyć modele Django, które używają backendu API REST XML (zamiast SQL). Jest to bardzo przydatne zwłaszcza podczas modelowania interfejsów API stron trzecich - otrzymujesz tę samą składnię QuerySet, do której jesteś przyzwyczajony. Możesz zainstalować go z PyPI.
XML z 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>
A teraz w 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'
Może także obsługiwać relacje i kolekcje. Używamy go codziennie w mocno używanym kodzie produkcyjnym, więc nawet jeśli jest to wersja beta, jest bardzo użyteczna. Ma również dobry zestaw kodów pośredniczących, które można wykorzystać w testach.
(Oświadczenie: chociaż nie jestem autorem tej biblioteki, teraz jestem komisarzem, popełniłem kilka drobnych zmian)