Jawaban:
Saya hanya akan mulai dengan tip dari diri saya sendiri :)
Gunakan os.path.dirname () di settings.py untuk menghindari nama file yang di-hardcode.
Jangan lacak hardcode di pengaturan Anda .py jika Anda ingin menjalankan proyek Anda di lokasi yang berbeda. Gunakan kode berikut di settings.py jika templat dan file statis Anda berada di dalam direktori proyek 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"),
)
Penghargaan: Saya mendapatkan tip ini dari screencast ' Django From the Ground Up '.
j = lambda filename: os.path.join(PROJECT_DIR, filename)
. Maka Anda hanya perlu mengetik j("static")
.
wontfix
keputusan tersebut.
Instal Django Command Extensions dan pygraphviz lalu keluarkan perintah berikut untuk mendapatkan visualisasi model Django yang benar-benar bagus:
./manage.py graph_models -a -g -o my_project.png
Gunakan dekorator django-menjengkelkan render_to
bukan 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))
Diedit untuk menunjukkan bahwa mengembalikan HttpResponse (seperti pengalihan) akan membuat hubungan pendek dekorator dan bekerja seperti yang Anda harapkan.
Ada satu set tag khusus yang saya gunakan di seluruh templat situs saya. Mencari cara untuk memuat ulang secara otomatis (KERING, ingat?), Saya menemukan yang berikut:
from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')
Jika Anda meletakkan ini di modul yang dimuat secara default (misalnya urlconf utama Anda), Anda akan memiliki tag dan filter dari modul tag kustom Anda yang tersedia di template apa pun, tanpa menggunakan {% load custom_tag_module %}
.
Argumen yang diteruskan ke template.add_to_builtins()
dapat berupa jalur modul apa pun; modul tag khusus Anda tidak harus hidup dalam aplikasi tertentu. Sebagai contoh, itu juga bisa menjadi modul di direktori root proyek Anda (mis. 'project.custom_tag_module'
).
Virtualenv + Python = life saver jika Anda bekerja pada beberapa proyek Django dan ada kemungkinan semuanya tidak bergantung pada versi Django / aplikasi yang sama.
virtualenv myNewEnv --no-site-packages
; . myNewEnv/bin/activate
; pip install django
; Dan itu berhasil!
Jangan kode-keras URL Anda!
Gunakan nama url sebagai gantinya, dan reverse
fungsinya untuk mendapatkan URL itu sendiri.
Saat Anda menentukan pemetaan URL Anda, berikan nama ke URL Anda.
urlpatterns += ('project.application.views'
url( r'^something/$', 'view_function', name="url-name" ),
....
)
Pastikan namanya unik per URL.
Saya biasanya memiliki format yang konsisten "view-appplication-view", misalnya "cbx-forum-thread" untuk tampilan thread.
UPDATE (tanpa malu-malu mencuri tambahan ayaz ):
Nama ini dapat digunakan dalam templat dengan url
tag .
url
tag ... Sikapnya adalah bahwa url tidak boleh berubah pula (jika Anda ingin bersikap ramah kepada Anda pengguna).
{% url path.to.view.name arg1 arg2 %}
docs.djangoproject.com/en/dev/ref/templates/builtins/…
reverse
seperti ini environment.filters['url'] = django.core.urlresolvers.reverse
dan Anda dapat menggunakannya di templat seperti: {{ 'view-name'|url(arg1, arg2)|e }}
("e" diperlukan untuk keluar dari beberapa karakter untuk dimasukkan dalam HTML)
Gunakan bilah alat debug django . Misalnya, ini memungkinkan untuk melihat semua permintaan SQL yang dilakukan saat menampilkan tampilan dan Anda juga dapat melihat stacktrace untuk salah satu dari mereka.
Jangan menulis halaman login Anda sendiri. Jika Anda menggunakan django.contrib.auth.
Rahasia sebenarnya yang kotor adalah jika Anda juga menggunakan django.contrib.admin, dan django.template.loaders.app_directories.load_template_source ada di loader template Anda , Anda bisa mendapatkan template Anda juga gratis!
# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
(r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
(r'^accounts/logout/$','views.logout'),
)
Katakanlah Anda memiliki model pengguna yang berbeda dan Anda ingin memasukkannya dalam setiap respons. Alih-alih melakukan ini:
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))
Proses konteks memberi Anda kemampuan untuk meneruskan variabel apa pun ke templat Anda. Saya biasanya menaruh milik saya di '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='')
Di settings.py
tambahkan baris berikut ke AndaTEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'my_project.apps.core.context.my_context',
...
)
Sekarang setiap kali permintaan dibuat itu termasuk my_user
kunci secara otomatis.
Saya menulis posting blog tentang ini beberapa bulan yang lalu jadi saya hanya akan memotong dan menempel:
Di luar kotak Django memberi Anda beberapa sinyal yang sangat berguna. Anda memiliki kemampuan untuk melakukan hal-hal sebelum dan sesudah menyimpan, init, menghapus, atau bahkan ketika permintaan sedang diproses. Jadi mari kita menjauh dari konsep dan menunjukkan bagaimana ini digunakan. Katakanlah kita punya 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)
Jadi, entah bagaimana, Anda ingin memberi tahu salah satu dari banyak layanan ping-blog yang kami buat pada posting baru, membangun kembali cache posting terbaru, dan men-tweet tentangnya. Baik dengan sinyal Anda memiliki kemampuan untuk melakukan semua ini tanpa harus menambahkan metode apa pun ke kelas 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)
Di sana kita pergi, dengan mendefinisikan fungsi itu dan menggunakan sinyal post_init untuk menghubungkan fungsi ke model Post dan menjalankannya setelah disimpan.
Ketika saya memulai, saya tidak tahu bahwa ada seorang Paginator , pastikan Anda tahu keberadaannya !!
Gunakan IPython untuk melompat ke kode Anda di tingkat mana pun dan debug menggunakan kekuatan IPython. Setelah Anda menginstal IPython, masukkan saja kode ini ke mana pun Anda ingin men-debug:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Kemudian, segarkan halaman, buka jendela runserver Anda dan Anda akan berada di jendela IPython interaktif.
Saya memiliki cuplikan yang diatur di TextMate jadi saya cukup ketik ipshell dan tekan tab. Saya tidak bisa hidup tanpanya.
ipdb
dan kemudian cukup ketikipdb.set_trace()
Jalankan server SMTP pengembangan yang hanya akan menampilkan apa pun yang dikirim kepadanya (jika Anda tidak ingin menginstal SMTP di server dev Anda.)
garis komando:
python -m smtpd -n -c DebuggingServer localhost:1025
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
..that akan mencetak email ke manage.py
output.
Dari dokumentasi django-admin :
Jika Anda menggunakan Bash shell, pertimbangkan untuk menginstal skrip penyelesaian Django bash, yang tinggal di extras/django_bash_completion
dalam distribusi Django. Ini memungkinkan penyelesaian tab django-admin.py
dan manage.py
perintah, sehingga Anda dapat, misalnya ...
django-admin.py
.sql
, kemudian [TAB], untuk melihat semua opsi yang tersedia yang namanya dimulai sql
.Fasilitas ./manage.py runserver_plus
yang datang dengan django_extensions benar-benar luar biasa.
Ini menciptakan halaman debug ditingkatkan yang, antara lain, menggunakan debugger Werkzeug untuk membuat konsol debugging interaktif untuk setiap titik dalam tumpukan (lihat screenshot). Ini juga menyediakan metode debugging kenyamanan yang sangat berguna dump()
untuk menampilkan informasi tentang suatu objek / bingkai.
Untuk menginstal, Anda dapat menggunakan pip:
pip install django_extensions
pip install Werkzeug
Kemudian tambahkan 'django_extensions'
ke INSTALLED_APPS
tuple Anda settings.py
dan mulai server pengembangan dengan ekstensi baru:
./manage.py runserver_plus
Ini akan mengubah cara Anda melakukan debug.
Saya suka menggunakan Python debugger pdb untuk men-debug proyek Django.
Tautan ini bermanfaat untuk mempelajari cara menggunakannya: http://www.ferg.org/papers/debugging_in_python.html
Saat mencoba bertukar data antara Django dan aplikasi lain, request.raw_post_data
adalah teman yang baik. Gunakan untuk menerima dan memproses kustom, katakanlah, data XML.
Dokumentasi: http://docs.djangoproject.com/en/dev/ref/request-response/
Gunakan Jinja2 bersama Django.
Jika Anda menemukan bahasa template Django sangat membatasi (seperti saya!) Maka Anda tidak perlu terjebak dengannya. Django fleksibel, dan bahasa templat longgar digabungkan ke seluruh sistem, jadi cukup plug-in bahasa templat lain dan gunakan untuk membuat tanggapan http Anda!
Saya menggunakan Jinja2 , hampir seperti versi yang didukung dari bahasa template Django, ia menggunakan sintaks yang sama, dan memungkinkan Anda untuk menggunakan ekspresi dalam pernyataan if! tidak perlu lagi membuat tag if seperti if_item_in_list
! Anda bisa mengatakan %{ if item in list %}
, atau {% if object.field < 10 %}
.
Tapi itu belum semuanya; ia memiliki lebih banyak fitur untuk memudahkan pembuatan template, yang tidak bisa saya lewati meskipun semuanya ada di sini.
Tambahkan assert False
kode tampilan Anda untuk membuang informasi debug.
5 / 0
diri saya sendiri. Kenapa lima? Tidak ada ide.
Ini menambah jawaban di atas tentang nama URL Django dan membalikkan pengiriman URL .
Nama-nama URL juga dapat digunakan secara efektif dalam template. Misalnya, untuk pola URL yang diberikan:
url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')
Anda dapat memiliki yang berikut di templat:
<a href="{% url project_team project.id %}">Team</a>
Karena Django "views" hanya perlu menjadi callable yang mengembalikan HttpResponse, Anda dapat dengan mudah membuat tampilan berbasis kelas seperti yang ada di Ruby on Rails dan kerangka kerja lainnya.
Ada beberapa cara untuk membuat tampilan berbasis kelas, inilah favorit saya:
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
Anda dapat menambahkan segala macam hal lainnya seperti penanganan permintaan bersyarat dan otorisasi dalam tampilan dasar Anda.
Setelah pengaturan tampilan Anda, urls.py Anda akan terlihat seperti ini:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('',
(r'^restview/', MyRestView.dispatch),
)
Alih-alih menggunakan render_to_response
untuk mengikat konteks Anda ke templat dan merendernya (yang biasanya ditunjukkan oleh dokumen Django) gunakan tampilan umum direct_to_template
. Itu melakukan hal yang render_to_response
sama tetapi tidak secara otomatis menambahkan RequestContext ke konteks templat, secara implisit memungkinkan pemroses konteks untuk digunakan. Anda dapat melakukan ini secara manual menggunakan render_to_response
, tetapi mengapa repot-repot? Ini hanya langkah lain untuk diingat dan LOC lain. Selain memanfaatkan pengolah konteks, memiliki RequestContext di template Anda memungkinkan Anda untuk melakukan hal-hal seperti:
<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a>
yang sangat bermanfaat. Bahkan, memberi +1 pada pandangan umum secara umum. Sebagian besar dokumen Django menunjukkannya sebagai pintasan karena bahkan tidak memiliki file views.py untuk aplikasi sederhana, tetapi Anda juga dapat menggunakannya di dalam fungsi tampilan Anda sendiri:
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
metode pintas baru dari Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
Saya tidak memiliki reputasi yang cukup untuk membalas komentar yang dimaksud, tetapi penting untuk dicatat bahwa jika Anda akan menggunakan Jinja , itu TIDAK mendukung karakter '-' dalam nama blok template, sementara Django melakukannya. Ini menyebabkan saya banyak masalah dan membuang-buang waktu untuk melacak pesan kesalahan yang sangat tidak jelas yang dihasilkannya.
The app webdesign sangat berguna ketika memulai untuk desain website Anda. Setelah diimpor, Anda dapat menambahkan ini untuk menghasilkan teks sampel:
{% load webdesign %}
{% lorem 5 p %}
django.db.models.get_model
memang memungkinkan Anda untuk mengambil model tanpa mengimpornya.
James menunjukkan betapa mudahnya bisa: "Kiat Django: Tulis tag templat yang lebih baik - Iterasi 4" .
Semua orang tahu ada server pengembangan yang dapat Anda jalankan dengan "manage.py runserver", tetapi apakah Anda tahu bahwa ada tampilan pengembangan untuk menyajikan file statis (CSS / JS / IMG) juga?
Pendatang baru selalu bingung karena Django tidak datang dengan cara apa pun untuk melayani file statis. Ini karena tim pengembang berpikir itu adalah pekerjaan untuk server Web kehidupan nyata.
Tetapi ketika mengembangkan, Anda mungkin tidak ingin mengatur Apache + mod_wisgi, itu berat. Kemudian Anda bisa menambahkan yang berikut ke urls.py:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media'}),
CSS / JS / IMG Anda akan tersedia di www.yoursite.com/site_media/.
Tentu saja, jangan menggunakannya di lingkungan produksi.
Saya belajar ini dari dokumentasi untuk thumbnail-sorl . Anda dapat menggunakan kata kunci "sebagai" dalam tag templat untuk menggunakan hasil panggilan di tempat lain dalam templat Anda.
Sebagai contoh:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Ini disebutkan secara sepintas dalam dokumentasi templatetag Django, tetapi hanya mengacu pada loop. Mereka tidak menyebut bahwa Anda dapat menggunakan ini di tempat lain (di mana saja?) Juga.
django.views.generic.list_detail.object_list - Ini menyediakan semua variabel template & template untuk pagination (salah satu dari mereka yang telah saya tuliskan-yang-seribu-kali-sekarang drudgeries). Membungkusnya memungkinkan untuk semua logika yang Anda butuhkan. Permata ini telah menyelamatkan saya berjam-jam untuk men-debug kesalahan satu per satu di halaman "Hasil Pencarian" saya dan membuat kode tampilan lebih bersih dalam proses.
IDE PyCharm adalah lingkungan yang baik untuk kode dan terutama debug, dengan dukungan bawaan untuk Django.
Gunakan xml_models untuk membuat model Django yang menggunakan backend XML REST API (bukan SQL satu). Ini sangat berguna terutama ketika memodelkan API pihak ketiga - Anda mendapatkan semua sintaks QuerySet yang sama dengan yang biasa Anda gunakan. Anda dapat menginstalnya dari PyPI.
XML dari 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>
Dan sekarang dengan 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'
Itu juga dapat menangani hubungan dan koleksi. Kami menggunakannya setiap hari dalam kode produksi yang banyak digunakan, jadi meskipun ini beta, itu sangat berguna. Ini juga memiliki set rintisan yang baik yang dapat Anda gunakan dalam tes Anda.
(Penafian: sementara saya bukan penulis perpustakaan ini, saya sekarang adalah seorang committer, telah membuat beberapa komitmen kecil)