เคล็ดลับและคุณสมบัติ Django สุดโปรด?


308

แรงบันดาลใจจากชุดคำถาม 'คุณสมบัติที่ซ่อนอยู่ของ ... ' ฉันอยากรู้เกี่ยวกับเคล็ดลับ Django ที่คุณชื่นชอบหรือรู้จักคุณสมบัติที่มีประโยชน์น้อยกว่า แต่เป็นประโยชน์ที่คุณรู้จัก

  • โปรดรวมเพียงหนึ่งเคล็ดลับต่อคำตอบ
  • เพิ่มข้อกำหนดรุ่น Django ถ้ามี

คำตอบ:


221

ฉันจะเริ่มด้วยเคล็ดลับจากตัวเอง :)

ใช้ os.path.dirname () ใน settings.py เพื่อหลีกเลี่ยง dirnames ฮาร์ดโค้ด

อย่าใช้เส้นทาง hardcode ใน 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 จากพื้นดินขึ้น '


75
คุณไม่ควรลงคะแนนคนที่ตอบคำถามของตัวเอง มันได้รับการสนับสนุนแม้ว่าจะถูกกำหนดล่วงหน้า
เปาโล Bergantino

19
นี่เป็นความคิดที่ดีที่ฉันยังคงเข้าใจยากว่าทำไมจึงไม่เป็นค่าเริ่มต้น มีกี่คนที่ทดสอบและปรับใช้ในเครื่องเดียวกัน
SingleNegationElimination

19
บรรเทาจากนี้คุณมักจะพิมพ์ os.path.join () j = lambda filename: os.path.join(PROJECT_DIR, filename)ซึ่งได้รับน่ารำคาญอย่างรวดเร็ว: j("static")แล้วคุณก็ต้องพิมพ์
wr.

13
หากคุณใช้ Windows ให้เปลี่ยนแบ็กสแลช: os.path.join (PROJECT_DIR, "templates") แทนที่ ('\\', '/')
Peter Mortensen

7
หากคุณชอบที่จะได้รับการแก้ไขในนี้ Django แสดงความคิดเห็นเพื่อcode.djangoproject.com/ticket/694ขอ devs หลักในการพิจารณาwontfixตัดสินใจ
sorin

128

ติดตั้งส่วนขยายคำสั่ง Djangoและpygraphvizจากนั้นออกคำสั่งต่อไปนี้เพื่อให้ได้รูปแบบภาพ Django ที่ดูดีมาก:

./manage.py graph_models -a -g -o my_project.png

ดีไม่สามารถรับ pygraphviz เพื่อติดตั้งอย่างถูกต้องใน windows แต่ยังสามารถแปลงจากไฟล์ dot โดยใช้ graphviz
monkut

ฉันชอบแบ่งปันแบบจำลองแผนภาพกับ +1 นี้อย่างแน่นอน
BozoJoe

มีตัวเลือก svg สำหรับสิ่งนี้หรือไม่?
Keyo

ดูเหมือนว่าภาพจะถูกจับออกไปในขณะนี้
Brian Wigginton

119

การใช้งานของ Django น่ารำคาญ มัณฑนากรแทนrender_torender_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 (เช่นการเปลี่ยนเส้นทาง) จะเป็นการลัดวงจรมัณฑนากรและทำงานตามที่คุณคาดหวัง


4
@becomingGuru - มันเกิดขึ้นโดยอัตโนมัติ
Dominic Rodger

15
นี่เป็นเรื่องปกติเว้นแต่คุณจะส่งคืน HttpResponseRedirect () บางส่วนและ render_to_response () บางส่วน จากนั้นการเปลี่ยนเส้นทางล้มเหลว
Matthew Schinckel

17
ฉันไม่ชอบมัน "ชัดเจนดีกว่าโดยปริยาย" มัณฑนากรไม่ได้บอกว่าจะให้ render_to
Tamás Szelei

2
@ Matthew Schinckel จริงๆแล้วมันจะไม่เลอะการเปลี่ยนเส้นทาง - ถ้าคุณคืนค่าวัตถุ HttpResponse มันจะผ่านมันไปโดยไม่ต้องแก้ไขมัน
Jiaaro

20
ฉันเชื่อว่าวิธีการนี้ได้รับการแก้ไขแล้วตั้งแต่ Django 1.3 ดู django.shortcuts.render () docs.djangoproject.com/en/dev/topics/http/shortcuts/#render
Dolph

101

มีชุดแท็กที่กำหนดเองที่ฉันใช้ทั่วทั้งเทมเพลตของไซต์ กำลังมองหาวิธีที่จะโหลดมันอัตโนมัติ (DRY จำได้ไหม) ฉันพบสิ่งต่อไปนี้:

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')


@Steef คุณเพิ่งช่วยฉันโหลดเวลา / heartache / bytes ได้ขอบคุณ
orokusaki

ดีจริงๆ. ขอบคุณ ด้วยที่เก็บแท็กที่กำหนดเองจะเป็นการดีที่จะแบ่งปันสิ่งต่างๆคุณไม่คิดเหรอ?
Leandro Ardissone

ดีมากจนกระทั่งมีคนอื่นต้องรักษารหัสของคุณ คิดว่า: "หลักการแห่งเวทมนตร์น้อยที่สุด"
รวย

96

Virtualenv + Python = ช่วยชีวิตหากคุณกำลังทำงานในโครงการ Django หลายโครงการและมีความเป็นไปได้ที่พวกเขาทั้งหมดจะไม่ขึ้นอยู่กับ Django / แอปพลิเคชันรุ่นเดียวกัน


15
นี่เป็นวิธีการหมุนเท่านั้น!
postfuturist

3
คุณสามารถเพิ่มลิงค์การสอนสำหรับ virtualenv กับ django ได้ไหม?
BozoJoe

2
@BozoJoe: ทำเช่นนี้ใน terminal ของคุณ: virtualenv myNewEnv --no-site-packages; . myNewEnv/bin/activate; pip install django; และมันก็ใช้งานได้!
SingleNegationElimination

87

อย่าเขียนโค้ดของคุณอย่างหนัก!

ใช้ชื่อ URLแทนและreverseฟังก์ชั่นเพื่อรับ URL นั้นเอง

เมื่อคุณกำหนดการแมป URL ให้ตั้งชื่อให้กับ URL ของคุณ

urlpatterns += ('project.application.views'
   url( r'^something/$', 'view_function', name="url-name" ),
   ....
)

ตรวจสอบให้แน่ใจว่าชื่อนั้นไม่ซ้ำกันต่อ URL

ฉันมักจะมีรูปแบบที่สอดคล้องกัน "project-appplication-view" เช่น "cbx-forum-thread" สำหรับมุมมองเธรด

อัปเดต (ขโมยการเพิ่มayaz อย่างไร้ยางอาย):

ชื่อนี้สามารถใช้ในแม่แบบที่มีแท็กurl


1
ฉันเห็นด้วย 100% กับอันนี้ ฉันเริ่มจากการใช้ URL ที่เขียนโค้ดยากและมันทำให้ฉันเป็นโครงการเมื่อฉันเปลี่ยนรูปแบบ URL รอบ ๆ เล็กน้อยเพื่อรองรับการเปลี่ยนแปลงบางอย่าง ฉันใช้เวลาในการย้อนกลับและขุดทุกอย่างและแทนที่ URL ที่เข้ารหัสยาก การร้องเรียนที่ใหญ่อย่างเดียวของฉันคือข้อผิดพลาดของแท็ก url จะทำลายทั้งหน้าในขณะที่ฮาร์ดโค้ดเพียงแค่ทำลิงก์แต่ละรายการให้ยุ่ง
ricree

21
นี่ไม่ใช่คุณสมบัติที่ซ่อนอยู่นี่คือแนวปฏิบัติที่ดีที่สุดและเป็นวิธีเดียวที่จะบินได้
Skylar Saveland

1
@skyl มันแทบจะ "วิธีเดียวในการบิน" ฉันอยู่ที่การวิ่งอย่าง Django และ Adrian Holovaty (หนึ่งในผู้สร้างของ Django) กล่าวว่าเขาไม่ได้ใช้urlแท็ก ... ท่าทางของเขาคือการที่ URL ไม่ควรเปลี่ยนแปลงต่อไป (ถ้าคุณต้องการเป็นมิตรกับคุณ ผู้ใช้)
TM

คุณสามารถใช้สิ่งนี้ในเทมเพลตเช่นเดียวกับใน{% url path.to.view.name arg1 arg2 %} docs.djangoproject.com/en/dev/ref/templates/builtins/…
SingleNegationElimination

หากคุณใช้ jinja2 เพียงเพิ่มreverseเช่นนี้environment.filters['url'] = django.core.urlresolvers.reverseและคุณสามารถใช้มันในเทมเพลตของคุณเช่น: {{ 'view-name'|url(arg1, arg2)|e }}(จำเป็นต้องใช้ "e" เพื่อหลีกเลี่ยงอักขระบางตัวเพื่อรวมไว้ใน HTML)
SingleNegationElimination

81

ใช้Django แก้ปัญหาแถบเครื่องมือ ตัวอย่างเช่นมันช่วยให้สามารถดูเคียวรี SQL ทั้งหมดที่ดำเนินการในขณะที่เรนเดอร์มุมมองและคุณยังสามารถดูสแต็คเทรซสำหรับรายการใด ๆ


79

อย่าเขียนหน้าเข้าสู่ระบบของคุณเอง หากคุณใช้ 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'),
)

1
เย็น! ฉันไม่รู้ว่าเราสามารถนำหน้าล็อกอินของผู้ดูแลระบบมาใช้ซ้ำได้ ขอบคุณ!
Joshua Partogi

66

โปรเซสเซอร์บริบทยอดเยี่ยม

สมมติว่าคุณมีรูปแบบผู้ใช้ที่แตกต่างกันและคุณต้องการรวมไว้ในการตอบกลับทุกครั้ง แทนที่จะทำสิ่งนี้:

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รหัสโดยอัตโนมัติ

สัญญาณยังชนะ

ฉันเขียนโพสต์บล็อกเกี่ยวกับเรื่องนี้เมื่อไม่กี่เดือนที่ผ่านมาดังนั้นฉันจะตัดและวาง:

ออกจากกล่อง Django ให้สัญญาณหลายอย่างที่มีประโยชน์อย่างเหลือเชื่อ คุณมีความสามารถในการทำสิ่งต่าง ๆ ล่วงหน้าและโพสต์บันทึกเริ่มต้นลบหรือแม้กระทั่งเมื่อมีการประมวลผลคำขอ ดังนั้นให้หลีกหนีจากแนวคิดและสาธิตวิธีการใช้งานเหล่านี้ สมมติว่าเรามีบล็อก

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)

ดังนั้นคุณต้องการแจ้งหนึ่งในบริการส่ง Ping บล็อกที่เราได้สร้างโพสต์ใหม่สร้างแคชโพสต์ล่าสุดและทวีตเกี่ยวกับมัน ดีกับสัญญาณที่คุณมีความสามารถในการทำทั้งหมดนี้โดยไม่ต้องเพิ่มวิธีการใด ๆ ในชั้นเรียนโพสต์

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 เพื่อเชื่อมต่อฟังก์ชั่นกับโมเดลโพสต์และดำเนินการหลังจากบันทึกแล้ว


4
สัญญาณของ Django เป็นคุณสมบัติที่ต้องมีสำหรับฉันในทุกวันนี้เมื่อเปรียบเทียบกรอบเว็บ การเขียนฟอรัมคู่สนทนาอย่างหลวม ๆ ซึ่งสามารถฟังพูดอัปเดตจากโมดูล "ลายเซ็น" แต่ไม่ต้องการให้โมดูลนั้นทำงานได้จริงและยังสามารถทำงานร่วมกับโมดูลที่ใช้งานร่วมกันได้ซึ่งใช้คุณสมบัติเดียวกัน ฉันไม่รู้ว่าทำไมสัญญาณไม่เป็นที่รู้จักและนิยมมากขึ้น
Lee B

สัญญาณมีความสำคัญมากในการหลีกเลี่ยงการเชื่อมต่อที่แน่นหนาและความยุ่งเหยิงของรหัสโดยทั่วไปหากเราใช้แอพที่นำมาใช้ซ้ำได้ในโครงการ คุณให้ตัวอย่างที่ดีเยี่ยมสำหรับการเชื่อมต่อแอพ django ที่หลวมสำหรับ +1 สำหรับสิ่งนี้
Lukasz Korzybski

คุณรู้หรือไม่ว่าสัญญาณเป็น async
Kedare

"สมมติว่าคุณมีรูปแบบผู้ใช้ที่แตกต่างกันและคุณต้องการรวมไว้ในการตอบกลับทุกครั้ง" - ใส่ผู้ใช้เข้ามาในเซสชั่น ที่ช่วยให้คุณตีฐานข้อมูลสำหรับทุกคำขอ
jammon

สัญญาณการโทรเป็นแบบซิงโครนัส ในความคิดของฉันกลไกการทำงานแบบอะซิงโครนัสบางประเภทนั้นเหมาะสำหรับการพูดการเผยแพร่บน Twitter / Facebook / etc (เช่น - rabbitmq) ดังนั้นผู้ใช้เว็บไซต์ภายนอกไม่ต้องขอ
gorsky

58

เมื่อฉันเริ่มต้นฉันไม่รู้ว่ามีPaginatorตรวจสอบให้แน่ใจว่าคุณรู้ว่ามีอยู่จริง !!


2
: D เหมือนกันสำหรับฉัน! ฉันใช้เวลาหลายวันไปกับการให้เลขหน้า!
vikingosegundo

46

ใช้IPythonเพื่อข้ามไปยังโค้ดของคุณในทุกระดับและทำการดีบักโดยใช้พลังของ IPython เมื่อคุณติดตั้ง IPython แล้วให้ใส่รหัสนี้ในทุกที่ที่คุณต้องการแก้ปัญหา:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()

จากนั้นรีเฟรชหน้าไปที่หน้าต่าง runserver ของคุณและคุณจะอยู่ในหน้าต่าง IPython แบบโต้ตอบ

ฉันมีชุดโค้ดใน TextMate ดังนั้นฉันจึงพิมพ์ ipshell และกด tab ฉันขาดไม่ได้


22
ดีกว่าติดตั้งipdbแล้วพิมพ์ipdb.set_trace()
Tomasz Zieliński

หรือใช้ดีบักเกอร์ของ Eclipse / PyDev :-)
jMyles

3
นำเข้า ipdb; ipdb.set_trace () FTW!
Hassek

43

เรียกใช้เซิร์ฟเวอร์ SMTP สำหรับการพัฒนาที่จะแสดงผลสิ่งใดก็ตามที่ถูกส่งไป (ถ้าคุณไม่ต้องการติดตั้ง SMTP บนเซิร์ฟเวอร์ dev ของคุณ)

บรรทัดคำสั่ง:

python -m smtpd -n -c DebuggingServer localhost:1025

12
คุณสามารถใช้คอนโซลและแบ็กเอนด์อีเมลไฟล์ใน django 1.2 เพื่อจุดประสงค์เดียวกัน
Dmitry Shevchenko

! โดดเด่น สมบูรณ์แบบสำหรับการลงทะเบียน! +1
BozoJoe

3
ทางเลือกใน Django 1.2 พร้อมการตั้งค่า: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' .. ที่จะพิมพ์อีเมลไปยังmanage.pyเอาต์พุต
vdboor

41

จากเอกสารdjango-admin :

หากคุณใช้ Bash shell ให้พิจารณาติดตั้งสคริปต์การทำให้สมบูรณ์ของ Django ซึ่งมีอยู่extras/django_bash_completionในการกระจาย Django มันช่วยให้แท็บเสร็จdjango-admin.pyและmanage.pyคำสั่งเพื่อให้คุณสามารถเช่น ...

  • ประเภทdjango-admin.py.
  • กด [TAB] เพื่อดูตัวเลือกที่มีทั้งหมด
  • ประเภทsqlแล้ว [Tab] sqlเพื่อดูตัวเลือกที่มีอยู่ทั้งหมดที่มีชื่อขึ้นต้นด้วย

1
สิ่งนี้มีประโยชน์มากกว่าที่ฉันคาดไว้ ขอบคุณ!
Jeeyoung Kim

นี่เป็นค่าเริ่มต้นใน Ubuntu รุ่นใหม่เป็นอย่างน้อย :-) ฉันประหลาดใจเมื่อครั้งแรกที่มันออกมาจากที่ไหนเลย
odinho - Velmont

40

สิ่งอำนวยความสะดวก./manage.py runserver_plusที่มาพร้อมกับdjango_extensions ยอดเยี่ยมจริงๆ

มันสร้างหน้าการดีบักขั้นสูงที่เหนือสิ่งอื่นใดใช้ตัวแก้จุดบกพร่อง Werkzeug เพื่อสร้างคอนโซลการแก้จุดบกพร่องแบบโต้ตอบสำหรับแต่ละจุดในกอง (ดูภาพหน้าจอ) นอกจากนี้ยังมีวิธีการตรวจแก้จุดบกพร่องความสะดวกสบายที่มีประโยชน์มากdump()สำหรับการแสดงข้อมูลเกี่ยวกับวัตถุ / เฟรม

ป้อนคำอธิบายรูปภาพที่นี่

ในการติดตั้งคุณสามารถใช้ pip:

pip install django_extensions
pip install Werkzeug

จากนั้นเพิ่ม'django_extensions'ในINSTALLED_APPStuple ของคุณsettings.pyและเริ่มต้นเซิร์ฟเวอร์การพัฒนาด้วยส่วนขยายใหม่

./manage.py runserver_plus

สิ่งนี้จะเปลี่ยนวิธีการแก้ไขข้อบกพร่องของคุณ


37

ฉันชอบใช้ Python debugger pdb เพื่อดีบักโครงการ Django

นี้เป็นลิงค์ที่เป็นประโยชน์สำหรับการเรียนรู้วิธีการใช้งาน: http://www.ferg.org/papers/debugging_in_python.html


13
นี่คือสวรรค์ หากต้องการให้ข้อมูลเพิ่มเติมเพียงเล็กน้อยให้เพิ่มสิ่งนี้: "import pdb; pdb.set_trace ()" บนบรรทัดใด ๆ ของรหัสของคุณ รีเฟรชหน้าของคุณ มันจะแขวน ตอนนี้ไปที่หน้าต่างเทอร์มินัลที่คุณใช้เซิร์ฟเวอร์การพัฒนา ตอนนี้มันควรจะเป็นเชลล์แบบโต้ตอบที่คุณสามารถเข้าถึงตัวแปรทั้งหมดได้ที่จุดนั้นในรหัสของคุณซึ่งคุณวางรหัสการดีบัก
priestc

37

เมื่อพยายามแลกเปลี่ยนข้อมูลระหว่าง Django กับแอปพลิเคชั่นอื่นrequest.raw_post_dataเป็นเพื่อนที่ดี ใช้เพื่อรับและกำหนดกระบวนการพูดข้อมูล XML

เอกสารประกอบ: http://docs.djangoproject.com/en/dev/ref/request-response/


5
นั่นเป็นวิธีที่คุณทำมัน ขอขอบคุณ +1
SingleNegationElimination

36

ใช้Jinja2ข้างๆ Django

หากคุณพบว่าภาษาเทมเพลต Django มีการ จำกัด อย่างมาก (เช่นฉัน!) คุณไม่จำเป็นต้องติดอยู่กับมัน Django มีความยืดหยุ่นและภาษาของเทมเพลตจะถูกผนวกเข้ากับระบบอื่น ๆ ที่เหลืออยู่ดังนั้นเพียงแค่ใช้ภาษาเทมเพลตอื่นและใช้เพื่อแสดงการตอบสนอง http ของคุณ!

ฉันใช้Jinja2มันเกือบจะเหมือนกับภาษาเทมเพลต django เวอร์ชันที่ใช้พลังงานเพิ่มขึ้นมันใช้ไวยากรณ์เดียวกันและช่วยให้คุณใช้นิพจน์ในถ้ามีคำสั่ง! ไม่ต้องสร้างแท็ก if-custom อีกต่อไปเช่นif_item_in_list! คุณก็สามารถพูดได้หรือ%{ if item in list %}{% if object.field < 10 %}

แต่นั่นไม่ใช่ทั้งหมด มันมีคุณสมบัติอื่น ๆ อีกมากมายที่จะทำให้การสร้างเทมเพลตง่ายขึ้นซึ่งฉันไม่สามารถไปได้ทั้งหมดในนั้น


ฉันใช้และเพลิดเพลินกับ Jinja2 เช่นกัน แต่ฉันพบว่ามีข้อต่อบางอย่างสำหรับแอปพลิเคชั่น "contrib" โดยเฉพาะอย่างยิ่งเครื่องมือการดูแลระบบนั้นเชื่อมโยงกับแม่แบบ Django อย่างแน่นหนา ฉันต้องสร้างมัณฑนากรล็อกอินใน contrib.auth เพื่อให้เป็นมิตรกับจินจา 2 แต่ก็ไม่ยากเกินไป
Joe Holloway

24
อย่าแทนที่ระบบแม่แบบด้วย jinja2 เพียงแค่ "เพิ่ม" มันอย่าลบ django templtes ใช้ Jinja2 สำหรับมุมมองของคุณและให้ผู้ดูแลระบบใช้ภาษาแม่แบบ django ต่อไป
hasen

4
ฉันเห็นด้วยอย่างมากกับเรื่องนี้ ไวยากรณ์ที่ จำกัด ของ Django นั้นทนทานได้เกือบตลอดเวลา แต่เมื่อคุณมาถึงจุดที่สร้างแท็กที่กำหนดเองและค้นหาว่าจริง ๆ แล้วมันยากแค่ไหน Jinja2 นั้นสูดอากาศบริสุทธิ์
SingleNegationElimination

นอกจากนี้หากคุณต้องการทำmetaprogramming ใด ๆในแหล่งที่มาของแม่แบบ Jinja2 ก็ดีกว่ามากเพราะคุณสามารถเข้าถึง AST ของแม่แบบที่แยกวิเคราะห์ได้โดยตรง การเดินตาม AST ทำให้งานต่าง ๆ เช่นการค้นหาแม่แบบที่ขยายแม่แบบฐานหรือแสดงรายการตัวแปรที่ไม่ได้ผูกไว้ในบล็อกต้นฉบับเทมเพลตซึ่งเกือบจะเป็นเรื่องง่าย
rcoder

5
โชคดีที่ Django 1.2 แท็ก IF นั้นฉลาดกว่ามาก
นิกซาน

35

เพิ่มassert Falseในรหัสมุมมองของคุณเพื่อดัมพ์ข้อมูลการดีบัก


4
ฉันคิดว่าการยืนยันว่าเท็จนั้นง่ายกว่า = D
4289 Jiaaro

13
หากคุณใช้งานโครงการของคุณในเซิร์ฟเวอร์ django dev ให้ใช้โมดูล pdbon ของ python เป็นวิธีที่มีประสิทธิภาพมากขึ้นในการดีบัก: import pdb; pdb.stack_trace ()
mazelife

pdb มีประโยชน์มากคุณมีโอกาสที่จะหมดเวลาการเชื่อมต่อเว้นแต่ว่าคุณจะทำการดีบักอย่างรวดเร็ว
สตีเฟ่น Paulger

4
ฉันมักจะใช้5 / 0ตัวเอง ทำไมถึงห้า ไม่มีความเห็น.
JasonSmith

@StephenPaulger จริงเหรอ? เบราว์เซอร์ของฉัน (firefox / w firebug) ดูเหมือนว่าเนื้อหาจะรอหลายนาทีเพื่อตอบสนองขณะที่ฉันดีบั๊ก
TM

34

นี้จะเพิ่มการตอบข้างต้นเกี่ยวกับชื่อ Django URL และเยี่ยงอย่าง

ชื่อ URL สามารถใช้อย่างมีประสิทธิภาพภายในเทมเพลต ตัวอย่างเช่นสำหรับรูปแบบ URL ที่กำหนด:

url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')

คุณสามารถมีสิ่งต่อไปนี้ในเทมเพลต:

<a href="{% url project_team project.id %}">Team</a>

27

เนื่องจาก Django "views" จะต้องเป็น callables ที่ส่งคืน 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

คุณสามารถเพิ่มสิ่งอื่น ๆ ได้ทุกประเภทเช่นการจัดการคำขอตามเงื่อนไขและการอนุญาตในมุมมองพื้นฐานของคุณ

เมื่อคุณได้ตั้งค่ามุมมองของคุณแล้ว URL ของคุณจะมีลักษณะดังนี้:

from django.conf.urls.defaults import *
from views import MyRestView

urlpatterns = patterns('',
    (r'^restview/', MyRestView.dispatch),
)

2
FWIW ผู้เขียน Django จริงใช้มุมมองระดับที่อยู่ในสถานที่ไม่กี่เช่น contrib.formtools: code.djangoproject.com/browser/django/trunk/django/contrib/...
mazelife

3
หากคุณเพิ่มวิธีการโทรคุณสามารถสร้างคลาสที่ชื่อว่า RestfulResource จากนั้นให้ urls.py ชี้ไปที่อินสแตนซ์
Stephen Paulger

1
ใหม่ (Django 1.3?) มุมมองทั่วไปเป็นคลาส
gorsky

21

แทนการใช้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 ส่วนใหญ่แสดงเป็นทางลัดแม้ว่าจะไม่มีไฟล์ views.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}
    )

ประหยัด LOC มากขึ้นโดยใช้ @render_to มัณฑนากรที่มีอยู่ใน django ที่น่ารำคาญ bitbucket.org/offline/django-annoying
pithyless

6
.. หรือใช้renderวิธีลัดใหม่จาก Django 1.3 ( docs.djangoproject.com/en/dev/topics/http/shortcuts/#render )
gorsky

20

ฉันไม่มีชื่อเสียงพอที่จะตอบความคิดเห็นที่เป็นปัญหา แต่สิ่งสำคัญที่ควรทราบคือถ้าคุณกำลังจะใช้Jinjaมันจะไม่สนับสนุนอักขระ '-' ในชื่อบล็อกเทมเพลตในขณะที่ Django ทำ สิ่งนี้ทำให้ฉันมีปัญหามากมายและเสียเวลาพยายามติดตามข้อความแสดงข้อผิดพลาดที่คลุมเครือที่สร้างขึ้น


หมายเหตุหนึ่งที่อาจหรืออาจใช้ไม่ได้กับ "ข้อความแสดงข้อผิดพลาดที่ชัดเจนจาก jinja" ตรวจสอบให้แน่ใจว่าตั้ง TEMPLATE_DEBUG = False ใน settings.py ด้วยเหตุผลบางอย่างนี้จะทำให้คุณมีข้อผิดพลาดที่มีความหมายจากแม่แบบ Jinja
Carl G

19

แอป Webdesignเป็นประโยชน์อย่างมากเมื่อเริ่มต้นในการออกแบบเว็บไซต์ของคุณ เมื่อนำเข้าแล้วคุณสามารถเพิ่มสิ่งนี้เพื่อสร้างข้อความตัวอย่าง:

{% load webdesign %}
{% lorem 5 p %}

4
FYI สำหรับทุกคนที่ใช้ Jinja2 แทนที่จะเป็นแม่แบบ Django คุณสามารถทำได้: {{lipsum (5)}}
Joe Holloway

19

django.db.models.get_model อนุญาตให้คุณดึงแบบจำลองโดยไม่นำเข้า

เจมส์แสดงให้เห็นว่ามีประโยชน์ก็สามารถ: "เคล็ดลับ Django: เขียนดีกว่าแท็กแม่แบบ - ย้ำ 4"


ดี: O! และที่นี่ฉันกำลังทำการนำเข้าขี้เกียจเมื่อใดก็ตามที่ฉันมีการพึ่งพาแบบวงกลม
Filip Dupanović

19

ทุกคนรู้ว่ามีเซิร์ฟเวอร์การพัฒนาที่คุณสามารถเรียกใช้ด้วย "Manage.py runserver" แต่คุณรู้หรือไม่ว่ามีมุมมองการพัฒนาสำหรับการให้บริการไฟล์คงที่ (CSS / JS / IMG) เช่นกัน

ผู้มาใหม่มักงงงวยอยู่เสมอเพราะ Django ไม่ได้ให้บริการไฟล์คงที่ นี่เป็นเพราะทีม dev คิดว่ามันเป็นงานสำหรับเว็บเซิร์ฟเวอร์ในชีวิตจริง

แต่เมื่อพัฒนาแล้วคุณอาจไม่ต้องการเซ็ตอัพ 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/

แน่นอนอย่าใช้มันในสภาพแวดล้อมการผลิต


6
ฉันใช้สิ่งนี้ในโหมด dev และเพื่อให้แน่ใจว่าฉันไม่ลืมที่จะปิดการใช้งานจริงฉันได้รวมกฎ URL นั้นไว้ใน DEBUG แบบมีเงื่อนไขเท่านั้น
sghael

18

ฉันได้เรียนรู้สิ่งนี้จากเอกสารประกอบสำหรับแอปsorl-thumbnails คุณสามารถใช้คำหลัก "เป็น" ในแท็กแม่แบบเพื่อใช้ผลการโทรที่อื่นในแม่แบบของคุณ

ตัวอย่างเช่น:

{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>

สิ่งนี้ถูกกล่าวถึงในการส่งผ่านเอกสาร Django templatetag แต่เป็นการอ้างอิงถึงลูปเท่านั้น พวกเขาไม่เรียกว่าคุณสามารถใช้สิ่งนี้ที่อื่น (ที่ใดก็ได้) เช่นกัน


7
หากคำหลัก "as" สามารถใช้กับเทมเพลตแท็กนั้นขึ้นอยู่กับแท็กเฉพาะนี้ ไม่ได้กำหนดโดย django แต่ใช้แท็กเดียวขึ้นอยู่กับความหมายของมัน ดูใน url-tag ที่ระบุไว้เพื่อดูว่ามีการใช้ "as" อย่างไร: code.djangoproject.com/browser/django/trunk/django/template/…
vikingosegundo

16

django.views.generic.list_detail.object_list - มันมีตัวแปรตรรกะและเทมเพลตทั้งหมดสำหรับการแบ่งหน้า (หนึ่งในบรรดา drudgeries ที่ฉันเคยเขียนว่าพันครั้ง - ตอนนี้) การห่อนั้นจะช่วยให้ตรรกะใด ๆ ที่คุณต้องการ อัญมณีนี้ช่วยฉันในการดีบักข้อผิดพลาดทีละหลายชั่วโมงในหน้า "ผลลัพธ์การค้นหา" ของฉันและทำให้โค้ดมุมมองสะอาดขึ้นในกระบวนการ


1
คุณสามารถค้นหารุ่นใหม่ของบทของหนังสือบน generic ผู้ชมในdjangobook.com/en/2.0/chapter11 หนึ่งในความคิดเห็นไปที่รุ่น Django pre-1.0 ของหนังสือ (หนังสือ Django 1.0)
Esteban Küber

16

PyCharm IDEเป็นสภาพแวดล้อมที่ดีในการเขียนโค้ดและการดีบักโดยเฉพาะอย่างยิ่งพร้อมการรองรับ Django ในตัว


14

ใช้xml_modelsเพื่อสร้างโมเดล Django ที่ใช้แบ็กเอนด์ 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>

และตอนนี้ในไพ ธ อน:

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'

นอกจากนี้ยังสามารถจัดการความสัมพันธ์และคอลเลกชัน เราใช้มันทุกวันในรหัสการผลิตที่ใช้งานหนักดังนั้นแม้ว่ามันจะเป็นรุ่นเบต้าที่สามารถใช้งานได้ดีมาก นอกจากนี้ยังมีชุดสมบูรณ์ที่คุณสามารถใช้ในการทดสอบของคุณ

(ข้อจำกัดความรับผิดชอบ: แม้ว่าฉันจะไม่ได้เป็นผู้เขียนของห้องสมุดนี้ แต่ตอนนี้ฉันเป็นผู้คอมมิชชันแล้ว


โครงการที่น่าสนใจติดตาม!
Sergey Golovchenko

ขอบคุณมันมีประโยชน์มาก :-)
godswearhats

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.