Antworten:
Ich fange nur mit einem Tipp von mir an :)
Verwenden Sie os.path.dirname () in settings.py, um fest codierte Dirnamen zu vermeiden.
Verwenden Sie keine Hardcode-Pfade in Ihrer settings.py, wenn Sie Ihr Projekt an verschiedenen Orten ausführen möchten. Verwenden Sie den folgenden Code in settings.py, wenn sich Ihre Vorlagen und statischen Dateien im Django-Projektverzeichnis befinden:
# 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"),
)
Credits: Ich habe diesen Tipp aus dem Screencast ' Django From the Ground Up ' erhalten.
j = lambda filename: os.path.join(PROJECT_DIR, filename)
. Dann müssen Sie nur noch tippen j("static")
.
wontfix
Entscheidung zu überdenken .
Installieren Sie Django Command Extensions und pygraphviz und geben Sie dann den folgenden Befehl ein, um eine wirklich gut aussehende Django- Modellvisualisierung zu erhalten:
./manage.py graph_models -a -g -o my_project.png
Verwenden Sie render_to
stattdessen den Dekorateur von django-nervrender_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))
Bearbeitet, um darauf hinzuweisen, dass das Zurückgeben einer HttpResponse (z. B. einer Umleitung) den Dekorator kurzschließt und wie erwartet funktioniert.
Es gibt eine Reihe von benutzerdefinierten Tags, die ich in allen Vorlagen meiner Website verwende. Auf der Suche nach einer Möglichkeit zum automatischen Laden (DRY, erinnerst du dich?) Fand ich Folgendes:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
Wenn Sie dies in ein Modul einfügen, das standardmäßig geladen ist (z. B. Ihre Haupt-URLconf), stehen die Tags und Filter Ihres benutzerdefinierten Tag-Moduls in einer beliebigen Vorlage zur Verfügung, ohne sie zu verwenden {% load custom_tag_module %}
.
Das übergebene Argument template.add_to_builtins()
kann ein beliebiger Modulpfad sein. Ihr benutzerdefiniertes Tag-Modul muss nicht in einer bestimmten Anwendung leben. Beispielsweise kann es sich auch um ein Modul im Stammverzeichnis Ihres Projekts handeln (z. B. 'project.custom_tag_module'
).
Virtualenv + Python = Lebensretter, wenn Sie an mehreren Django-Projekten arbeiten und die Möglichkeit besteht, dass nicht alle von derselben Version von Django / einer Anwendung abhängen.
virtualenv myNewEnv --no-site-packages
; . myNewEnv/bin/activate
;; pip install django
;; Und es funktioniert einfach!
Codieren Sie Ihre URLs nicht fest!
Verwenden Sie stattdessen URL-Namen und diereverse
Funktion, um die URL selbst abzurufen.
Wenn Sie Ihre URL-Zuordnungen definieren, geben Sie Ihren URLs Namen.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Stellen Sie sicher, dass der Name pro URL eindeutig ist.
Normalerweise habe ich ein konsistentes Format "Projektanwendungsansicht", z. B. "cbx-forum-thread" für eine Threadansicht.
UPDATE (schamlos Ayaz 'Hinzufügung stehlend ):
Dieser Name kann in Vorlagen mit dem url
Tag verwendet werden .
url
Tag ... Seine Haltung ist, dass sich URLs sowieso nicht ändern sollten (wenn Sie freundlich zu Ihnen sein möchten Benutzer).
{% url path.to.view.name arg1 arg2 %}
docs.djangoproject.com/de/dev/ref/templates/builtins/…
reverse
wie folgt environment.filters['url'] = django.core.urlresolvers.reverse
und Sie können es in Ihren Vorlagen verwenden , etwa so: {{ 'view-name'|url(arg1, arg2)|e }}
(das „e“ benötigt wird , einige Zeichen für die Aufnahme in HTML zu entkommen)
Verwenden Sie die Django-Debug-Symbolleiste . Sie können beispielsweise alle SQL-Abfragen anzeigen, die beim Rendern der Ansicht ausgeführt wurden, und Sie können auch die Stapelverfolgung für jede dieser Abfragen anzeigen.
Schreiben Sie keine eigenen Anmeldeseiten. Wenn Sie django.contrib.auth verwenden.
Das wahre, schmutzige Geheimnis ist, dass Sie Ihre Vorlagen auch kostenlos erhalten können , wenn Sie auch django.contrib.admin verwenden und django.template.loaders.app_directories.load_template_source in Ihren Vorlagenladern enthalten ist !
# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
(r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
(r'^accounts/logout/$','views.logout'),
)
Angenommen, Sie haben ein anderes Benutzermodell und möchten dies in jede Antwort einbeziehen. Anstatt dies zu tun:
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))
Mit Kontextprozessen können Sie jede Variable an Ihre Vorlagen übergeben. Normalerweise setze ich meine ein '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='')
Fügen settings.py
Sie in Ihrem die folgende Zeile zu Ihrem hinzuTEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
Jedes Mal, wenn eine Anfrage gestellt wird, wird der my_user
Schlüssel automatisch hinzugefügt.
Ich habe vor ein paar Monaten einen Blog-Beitrag darüber geschrieben, also werde ich einfach ausschneiden und einfügen:
Nach dem Auspacken gibt Ihnen Django mehrere Signale, die unglaublich nützlich sind. Sie haben die Möglichkeit, Dinge vor und nach dem Speichern, Initiieren, Löschen oder sogar während der Bearbeitung einer Anfrage zu erledigen. Lassen Sie uns also von den Konzepten weggehen und zeigen, wie diese verwendet werden. Angenommen, wir haben einen Blog
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)
Irgendwie möchten Sie einen der vielen Blog-Ping-Dienste benachrichtigen, die wir für einen neuen Beitrag erstellt haben, den Cache für die neuesten Beiträge neu erstellen und darüber twittern. Mit Signalen haben Sie die Möglichkeit, all dies zu tun, ohne der Post-Klasse Methoden hinzufügen zu müssen.
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)
Los geht's, indem wir diese Funktion definieren und das post_init-Signal verwenden, um die Funktion mit dem Post-Modell zu verbinden und sie auszuführen, nachdem sie gespeichert wurde.
Als ich anfing, wusste ich nicht, dass es einen Paginator gibt , stellen Sie sicher, dass Sie von seiner Existenz wissen !!
Verwenden Sie IPython, um auf jeder Ebene in Ihren Code zu springen und mit IPython zu debuggen. Sobald Sie IPython installiert haben, geben Sie diesen Code einfach dort ein, wo Sie debuggen möchten:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Aktualisieren Sie dann die Seite, gehen Sie zu Ihrem Runserver-Fenster und Sie befinden sich in einem interaktiven IPython-Fenster.
Ich habe ein Snippet in TextMate eingerichtet, also tippe ich einfach ipshell und drücke die Tabulatortaste. Ich könnte nicht ohne leben.
ipdb
und dann einfach tippenipdb.set_trace()
Führen Sie einen Entwicklungs-SMTP-Server aus, der nur das ausgibt, was an ihn gesendet wird (wenn Sie SMTP nicht tatsächlich auf Ihrem Entwicklungsserver installieren möchten).
Befehlszeile:
python -m smtpd -n -c DebuggingServer localhost:1025
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
..das wird die E-Mail an die manage.py
Ausgabe drucken .
Aus der Django-Admin-Dokumentation :
Wenn Sie die Bash-Shell verwenden, sollten Sie das Django-Bash-Abschlussskript installieren, das extras/django_bash_completion
in der Django-Distribution enthalten ist. Es ermöglicht das Ausfüllen von Registerkarten django-admin.py
und manage.py
Befehle, sodass Sie beispielsweise ...
django-admin.py
.sql
dann [TAB] ein, um alle verfügbaren Optionen anzuzeigen, deren Namen mit beginnen sql
.Die ./manage.py runserver_plus
mit django_extensions gelieferte Einrichtung ist wirklich fantastisch.
Es wird eine erweiterte Debug-Seite erstellt, die unter anderem den Werkzeug-Debugger verwendet, um interaktive Debugging-Konsolen für jeden Punkt im Stapel zu erstellen (siehe Screenshot). Es bietet auch eine sehr nützliche Debugging-Methode dump()
zum Anzeigen von Informationen zu einem Objekt / Frame.
Zur Installation können Sie pip verwenden:
pip install django_extensions
pip install Werkzeug
Fügen Sie 'django_extensions'
dann Ihrem INSTALLED_APPS
Tupel hinzu settings.py
und starten Sie den Entwicklungsserver mit der neuen Erweiterung:
./manage.py runserver_plus
Dies ändert die Art und Weise, wie Sie debuggen.
Ich verwende gerne die Python-Debugger-PDF, um Django-Projekte zu debuggen.
Dies ist ein hilfreicher Link, um zu lernen, wie man es benutzt: http://www.ferg.org/papers/debugging_in_python.html
Wenn Sie versuchen, Daten zwischen Django und einer anderen Anwendung auszutauschen, request.raw_post_data
ist dies ein guter Freund. Verwenden Sie diese Option, um beispielsweise XML-Daten zu empfangen und benutzerdefiniert zu verarbeiten.
Dokumentation: http://docs.djangoproject.com/de/dev/ref/request-response/
Verwenden Sie Jinja2 neben Django.
Wenn Sie die Django-Vorlagensprache als äußerst einschränkend empfinden (wie ich!), Müssen Sie sich nicht daran halten. Django ist flexibel und die Vorlagensprache ist lose mit dem Rest des Systems verbunden. Schließen Sie also einfach eine andere Vorlagensprache an und verwenden Sie sie, um Ihre http-Antworten zu rendern!
Ich benutze Jinja2 , es ist fast wie eine aktivierte Version der Django-Vorlagensprache, es verwendet dieselbe Syntax und ermöglicht es Ihnen, Ausdrücke in if-Anweisungen zu verwenden! keine benutzerdefinierten if-tags mehr erstellen wie if_item_in_list
! Sie können einfach sagen %{ if item in list %}
, oder{% if object.field < 10 %}
.
Aber das ist nicht alles; Es hat viele weitere Funktionen, um die Erstellung von Vorlagen zu vereinfachen, die ich hier nicht alle durchgehen kann.
Fügen Sie assert False
Ihren Ansichtscode hinzu, um Debug-Informationen zu sichern.
5 / 0
mich immer . Warum fünf? Keine Ahnung.
Dies ergänzt die obige Antwort zu Django-URL-Namen und dem umgekehrten URL-Versand .
Die URL-Namen können auch effektiv in Vorlagen verwendet werden. Zum Beispiel für ein bestimmtes URL-Muster:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
In Vorlagen können Sie Folgendes haben:
<a href="{% url project_team project.id %}">Team</a>
Da Django-Ansichten nur aufrufbare Dateien sein müssen, die eine HttpResponse zurückgeben, können Sie problemlos klassenbasierte Ansichten wie in Ruby on Rails und anderen Frameworks erstellen.
Es gibt verschiedene Möglichkeiten, klassenbasierte Ansichten zu erstellen. Hier ist mein Favorit:
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
Sie können in Ihrer Basisansicht alle möglichen anderen Dinge wie die bedingte Bearbeitung und Autorisierung von Anforderungen hinzufügen.
Sobald Sie Ihre Ansichten eingerichtet haben, sieht Ihre urls.py ungefähr so aus:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('',
(r'^restview/', MyRestView.dispatch),
)
render_to_response
Verwenden Sie die generische Ansicht, anstatt Ihren Kontext an eine Vorlage zu binden und diese zu rendern (wie in den Django-Dokumenten normalerweise gezeigt) direct_to_template
. Es macht dasselbe wie es tut, render_to_response
fügt aber automatisch RequestContext zum Vorlagenkontext hinzu, wodurch implizit die Verwendung von Kontextprozessoren ermöglicht wird. Sie können dies manuell tun render_to_response
, aber warum sich die Mühe machen? Es ist nur ein weiterer Schritt zum Erinnern und ein weiterer LOC. Mit RequestContext in Ihrer Vorlage können Sie nicht nur Kontextprozessoren verwenden, sondern auch Folgendes tun:
<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a>
das ist sehr nützlich. In der Tat +1 auf generische Ansichten im Allgemeinen. In den Django-Dokumenten werden sie meistens als Verknüpfungen angezeigt, wenn Sie nicht einmal eine views.py-Datei für einfache Apps haben. Sie können sie jedoch auch in Ihren eigenen Ansichtsfunktionen verwenden:
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
Verknüpfungsmethode aus Django 1.3 ( docs.djangoproject.com/de/dev/topics/http/shortcuts/#render )
Ich habe nicht genug Ruf, um auf den fraglichen Kommentar zu antworten, aber es ist wichtig zu beachten, dass wenn Sie Jinja verwenden , das Zeichen '-' in Vorlagenblocknamen NICHT unterstützt wird, während Django dies tut. Dies verursachte mir viele Probleme und verschwendete Zeit damit, die sehr dunkle Fehlermeldung aufzuspüren, die sie erzeugte.
Die Webdesign-App ist sehr nützlich, wenn Sie mit dem Design Ihrer Website beginnen. Nach dem Import können Sie diesen hinzufügen, um Beispieltext zu generieren:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model
ermöglicht es Ihnen, ein Modell abzurufen, ohne es zu importieren.
James zeigt, wie praktisch es sein kann: "Django-Tipps: Schreiben Sie bessere Vorlagen-Tags - Iteration 4" .
Jeder weiß, dass es einen Entwicklungsserver gibt, den Sie mit "manage.py runserver" ausführen können, aber wussten Sie, dass es auch eine Entwicklungsansicht für die Bereitstellung statischer Dateien (CSS / JS / IMG) gibt?
Neulinge sind immer verwirrt, weil Django keine Möglichkeit bietet, statische Dateien bereitzustellen. Dies liegt daran, dass das Entwicklerteam der Meinung ist, dass dies der Job für einen echten Webserver ist.
Aber während der Entwicklung möchten Sie möglicherweise Apache + mod_wisgi nicht einrichten, es ist schwer. Dann können Sie einfach Folgendes zu urls.py hinzufügen:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
Ihr CSS / JS / IMG ist unter www.yoursite.com/site_media/ verfügbar.
Verwenden Sie es natürlich nicht in einer Produktionsumgebung.
Ich habe dies aus der Dokumentation für die Sorl-Thumbnails gelernt App . Sie können das Schlüsselwort "as" in Vorlagen-Tags verwenden, um die Ergebnisse des Aufrufs an einer anderen Stelle in Ihrer Vorlage zu verwenden.
Zum Beispiel:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Dies wird im Vorbeigehen in der Django-Templatetag-Dokumentation erwähnt, jedoch nur in Bezug auf Schleifen. Sie rufen nicht dazu auf, dass Sie dies auch anderswo (irgendwo?) Verwenden können.
django.views.generic.list_detail.object_list - Es enthält alle Logik- und Vorlagenvariablen für die Paginierung (eine der Plackereien, die ich tausendmal geschrieben habe). Das Einwickeln ermöglicht jede Logik, die Sie benötigen. Dieses Juwel hat mir viele Stunden des Debuggens von Fehlern nacheinander auf meinen "Suchergebnisseiten" erspart und macht den Ansichtscode dabei sauberer.
PyCharm IDE ist eine schöne Umgebung zum Codieren und insbesondere zum Debuggen mit integrierter Unterstützung für Django.
Verwenden Sie xml_models , um Django-Modelle zu erstellen, die ein XML-REST-API-Backend (anstelle eines SQL-Backends) verwenden. Dies ist besonders beim Modellieren von APIs von Drittanbietern sehr nützlich. Sie erhalten dieselbe QuerySet-Syntax, die Sie gewohnt sind. Sie können es von PyPI installieren.
XML von einer 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>
Und jetzt in 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'
Es kann auch Beziehungen und Sammlungen verarbeiten. Wir verwenden es jeden Tag in häufig verwendetem Produktionscode. Obwohl es sich um eine Beta-Version handelt, ist es sehr benutzerfreundlich. Es hat auch eine gute Reihe von Stubs, die Sie in Ihren Tests verwenden können.
(Haftungsausschluss: Obwohl ich nicht der Autor dieser Bibliothek bin, bin ich jetzt ein Committer, nachdem ich einige kleinere Commits gemacht habe.)