Risposte:
Sto per iniziare con un suggerimento da parte mia :)
Utilizzare os.path.dirname () in settings.py per evitare dirnomi codificati.
Non tracciare il percorso del codice nelle impostazioni.py se si desidera eseguire il progetto in posizioni diverse. Utilizzare il seguente codice in settings.py se i modelli e i file statici si trovano nella directory del progetto 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"),
)
Riconoscimenti: ho ricevuto questo consiglio dallo screencast " Django From the Ground Up ".
j = lambda filename: os.path.join(PROJECT_DIR, filename)
. Quindi devi solo digitare j("static")
.
wontfix
decisione.
Installa Django Command Extensions e pygraphviz e quindi lancia il seguente comando per ottenere una visualizzazione del modello Django davvero carina:
./manage.py graph_models -a -g -o my_project.png
Usa invece il decoratore di django-fastidioso .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))
Modificato per sottolineare che la restituzione di un HttpResponse (come un reindirizzamento) farà cortocircuitare il decoratore e funzionerà come previsto.
C'è una serie di tag personalizzati che utilizzo in tutti i modelli del mio sito. Alla ricerca di un modo per caricarlo automaticamente (DRY, ricordi?), Ho trovato quanto segue:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
Se lo metti in un modulo caricato per impostazione predefinita (ad esempio il tuo urlconf principale), avrai i tag e i filtri del tuo modulo tag personalizzato disponibili in qualsiasi modello, senza usare {% load custom_tag_module %}
.
L'argomento passato a template.add_to_builtins()
può essere qualsiasi percorso del modulo; il tuo modulo tag personalizzato non deve vivere in un'applicazione specifica. Ad esempio, può anche essere un modulo nella directory principale del progetto (ad es. 'project.custom_tag_module'
).
Virtualenv + Python = salvavita se stai lavorando su più progetti Django e c'è la possibilità che tutti non dipendano dalla stessa versione di Django / un'applicazione.
virtualenv myNewEnv --no-site-packages
; . myNewEnv/bin/activate
; pip install django
; E funziona e basta!
Non codificare i tuoi URL!
Utilizzare invece i nomi URL e la reverse
funzione per ottenere l'URL stesso.
Quando definisci i tuoi mapping URL, dai un nome ai tuoi URL.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Assicurati che il nome sia univoco per URL.
Di solito ho un formato coerente "project-appplication-view", ad esempio "cbx-forum-thread" per una vista thread.
AGGIORNAMENTO (rubare senza vergogna l'aggiunta di Ayaz ):
Questo nome può essere utilizzato nei modelli con il url
tag .
url
tag ... La sua posizione è che gli URL non dovrebbero cambiare comunque (se vuoi essere amichevole con il tuo utenti).
{% url path.to.view.name arg1 arg2 %}
docs.djangoproject.com/en/dev/ref/templates/builtins/…
reverse
così environment.filters['url'] = django.core.urlresolvers.reverse
e puoi usarlo nei tuoi modelli in questo modo: {{ 'view-name'|url(arg1, arg2)|e }}
(la "e" è necessaria per sfuggire ad alcuni caratteri per l'inclusione in HTML)
Usa la barra degli strumenti di debug di django . Ad esempio, consente di visualizzare tutte le query SQL eseguite durante il rendering della vista ed è anche possibile visualizzare stacktrace per ognuna di esse.
Non scrivere le tue pagine di accesso. Se stai usando django.contrib.auth.
Il vero, sporco segreto è che se stai usando anche django.contrib.admin e django.template.loaders.app_directories.load_template_source è nei tuoi caricatori di modelli, puoi anche liberare i tuoi modelli!
# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
(r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
(r'^accounts/logout/$','views.logout'),
)
Supponi di avere un modello utente diverso e desideri includerlo in ogni risposta. Invece di fare questo:
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))
I processi di contesto ti danno la possibilità di passare qualsiasi variabile ai tuoi modelli. Di solito inserisco il mio '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='')
Nel tuo settings.py
aggiungi la seguente riga al tuoTEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
Ora ogni volta che viene fatta una richiesta include my_user
automaticamente la chiave.
Ho scritto un post sul blog alcuni mesi fa, quindi ho intenzione di tagliare e incollare:
Out of the box Django ti dà diversi segnali che sono incredibilmente utili. Hai la possibilità di fare le cose pre e postare il salvataggio, l'iniz, l'eliminazione o anche quando una richiesta viene elaborata. Quindi, allontaniamoci dai concetti e dimostriamo come vengono utilizzati. Supponiamo di avere un 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)
Quindi, in qualche modo, vuoi avvisare uno dei tanti servizi di ping-blog che abbiamo creato un nuovo post, ricostruire la cache dei post più recenti e twittare su di esso. Bene, con i segnali hai la possibilità di fare tutto questo senza dover aggiungere alcun metodo alla classe 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)
Andiamo, definendo quella funzione e usando il segnale post_init per connettere la funzione al modello Post ed eseguirla dopo che è stata salvata.
Quando stavo iniziando, non sapevo che esistesse un paginatore , assicurati di conoscerne l'esistenza !!
Usa IPython per saltare nel tuo codice a qualsiasi livello ed eseguire il debug usando la potenza di IPython. Dopo aver installato IPython, inserisci questo codice ovunque desideri eseguire il debug:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Quindi, aggiorna la pagina, vai alla finestra del tuo server e sarai in una finestra interattiva di IPython.
Ho uno snippet impostato in TextMate, quindi digito ipshell e premi tab. Non potrei vivere senza di essa.
ipdb
e quindi digitareipdb.set_trace()
Esegui un server SMTP di sviluppo che produrrà semplicemente tutto ciò che gli viene inviato (se non desideri installare effettivamente SMTP sul tuo server di sviluppo).
riga di comando:
python -m smtpd -n -c DebuggingServer localhost:1025
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
.. che stamperà l'e-mail manage.py
sull'output.
Dalla documentazione di django-admin :
Se usi la shell Bash, prendi in considerazione l'installazione dello script di completamento bash di Django, che vive nella extras/django_bash_completion
distribuzione di Django. Abilita il completamento con tabulazione django-admin.py
e i manage.py
comandi, in modo da poter, ad esempio ...
django-admin.py
.sql
, quindi [TAB], per visualizzare tutte le opzioni disponibili i cui nomi iniziano con sql
.La facilità./manage.py runserver_plus
fornita con django_extensions è davvero fantastica.
Crea una pagina di debug migliorata che, tra le altre cose, utilizza il debugger Werkzeug per creare console di debug interattive per ogni punto dello stack (vedi screenshot). Fornisce inoltre un metodo di debug molto utile dump()
per la visualizzazione di informazioni su un oggetto / frame.
Per installare, puoi usare pip:
pip install django_extensions
pip install Werkzeug
Quindi aggiungi la 'django_extensions'
tua INSTALLED_APPS
tupla settings.py
e avvia il server di sviluppo con la nuova estensione:
./manage.py runserver_plus
Questo cambierà il modo in cui esegui il debug.
Mi piace usare il pdb di debug di Python per eseguire il debug di progetti Django.
Questo è un link utile per imparare a usarlo: http://www.ferg.org/papers/debugging_in_python.html
Quando si tenta di scambiare dati tra Django e un'altra applicazione, request.raw_post_data
è un buon amico. Usalo per ricevere e processare, per esempio, dati XML.
Documentazione: http://docs.djangoproject.com/en/dev/ref/request-response/
Usa Jinja2 insieme a Django.
Se trovi che il linguaggio del modello di Django è estremamente restrittivo (come me!), Non devi essere bloccato con esso. Django è flessibile e il linguaggio dei template è liberamente associato al resto del sistema, quindi basta collegare un altro linguaggio dei template e usarlo per rendere le tue risposte http!
Uso Jinja2 , è quasi come una versione potenziata del linguaggio template django, usa la stessa sintassi e ti permette di usare espressioni in if statement! non creare più tag if personalizzati come if_item_in_list
! puoi semplicemente dire %{ if item in list %}
, o{% if object.field < 10 %}
.
Ma non è tutto; ha molte più funzioni per facilitare la creazione di modelli, che non posso seguire tutte qui.
Aggiungi assert False
il codice di visualizzazione per scaricare le informazioni di debug.
5 / 0
me stesso. Perché cinque? Nessuna idea.
Ciò si aggiunge alla risposta sopra relativa ai nomi degli URL Django e all'invio inverso degli URL .
I nomi URL possono anche essere effettivamente utilizzati all'interno dei modelli. Ad esempio, per un determinato pattern URL:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
puoi avere i seguenti modelli:
<a href="{% url project_team project.id %}">Team</a>
Poiché le "viste" di Django devono essere solo callable che restituiscono un HttpResponse, è possibile creare facilmente viste basate su classi come quelle di Ruby on Rails e di altri framework.
Esistono diversi modi per creare viste basate su classi, ecco la mia preferita:
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
Puoi aggiungere ogni sorta di altre cose come la gestione e l'autorizzazione condizionale delle richieste nella vista di base.
Dopo aver configurato le visualizzazioni, urls.py apparirà in questo modo:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('',
(r'^restview/', MyRestView.dispatch),
)
Invece di usare render_to_response
per associare il tuo contesto a un modello e renderlo (che è quello che i documenti Django mostrano di solito) usa la vista generica direct_to_template
. Fa la stessa cosa render_to_response
, ma aggiunge automaticamente RequestContext al contesto del modello, consentendo implicitamente l'uso dei processori di contesto. Puoi farlo manualmente usando render_to_response
, ma perché preoccuparsi? È solo un altro passo da ricordare e un altro LOC. Oltre a utilizzare i processori di contesto, avere RequestContext nel tuo modello ti consente di fare cose come:
<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a>
che è molto utile. In effetti, +1 su viste generiche in generale. I documenti Django li mostrano principalmente come scorciatoie per non avere nemmeno un file views.py per app semplici, ma puoi anche usarli all'interno delle tue funzioni di visualizzazione:
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
metodo di scelta rapida da Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
Non ho abbastanza reputazione per rispondere al commento in questione, ma è importante notare che se stai per usare Jinja , NON supporta il carattere "-" nei nomi dei blocchi modello, mentre Django lo fa. Ciò mi ha causato molti problemi e ha perso tempo a cercare di rintracciare il messaggio di errore molto oscuro che ha generato.
L' app webdesign è molto utile quando si inizia a progettare il tuo sito Web. Una volta importato, puoi aggiungerlo per generare testo di esempio:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model
ti consente di recuperare un modello senza importarlo.
James mostra quanto può essere utile: "Suggerimenti Django: Scrivi tag modello migliori - Iterazione 4" .
Tutti sanno che esiste un server di sviluppo che puoi eseguire con "manage.py RunServer", ma sapevi che esiste anche una vista di sviluppo per la gestione di file statici (CSS / JS / IMG)?
I nuovi arrivati sono sempre perplessi perché Django non ha alcun modo di servire file statici. Questo perché il team di sviluppo pensa che sia il lavoro per un server Web nella vita reale.
Ma durante lo sviluppo, potresti non voler configurare Apache + mod_wisgi, è pesante. Quindi puoi semplicemente aggiungere quanto segue a urls.py:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
Il tuo CSS / JS / IMG sarà disponibile su www.yoursite.com/site_media/.
Naturalmente, non utilizzarlo in un ambiente di produzione.
L'ho imparato dalla documentazione per le miniature delle sorl app . Puoi utilizzare la parola chiave "as" nei tag del modello per utilizzare i risultati della chiamata altrove nel modello.
Per esempio:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Questo è menzionato nel passaggio nella documentazione del templatetag di Django, ma solo in riferimento ai loop. Non dicono che puoi usarlo anche altrove (ovunque?).
django.views.generic.list_detail.object_list - Fornisce tutte le variabili logiche e template per l'impaginazione (uno di quei drudgeries che ho scritto mille volte). Avvolgendolo consente qualsiasi logica di cui hai bisogno. Questa gemma mi ha risparmiato molte ore di debug degli errori off-by-one nelle mie pagine "Risultati della ricerca" e rende il codice di visualizzazione più pulito nel processo.
PyCharm IDE è un ambiente piacevole per la codifica e soprattutto per il debug, con supporto integrato per Django.
Usa xml_models per creare modelli Django che utilizzano un back-end XML REST API (anziché SQL). Ciò è molto utile soprattutto quando si modellano API di terze parti: si ottiene la stessa sintassi QuerySet a cui si è abituati. Puoi installarlo da PyPI.
XML da un'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>
E ora 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'
Può anche gestire relazioni e raccolte. Lo usiamo ogni giorno nel codice di produzione molto usato, quindi anche se è beta è molto utilizzabile. Ha anche una buona serie di matrici che puoi usare nei tuoi test.
(Dichiarazione di non responsabilità: mentre non sono l'autore di questa biblioteca, ora sono committer, dopo aver fatto alcuni commit minori)