วิธีแก้ปัญหาใน Django วิธีที่ดี? [ปิด]


587

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

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

แต่สิ่งนี้สามารถปรับปรุงได้? มีเครื่องมือที่ดีหรือวิธีที่ดีกว่าในการดีบักรหัส Django ของคุณหรือไม่


2
ฉันชอบที่จะใช้ django-debug-toolbar มันมีประโยชน์มาก
Diego Vinícius

1
หรือใช้ Visual Studio Code ที่สร้างขึ้นในดีบัก Python ตามที่อธิบายไว้ที่นี่code.visualstudio.com/docs/python/tutorial-django
Nick T

คำตอบ:


536

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

import pdb; pdb.set_trace()

หรือ

breakpoint()  #from Python3.7

หากคุณพยายามโหลดหน้านั้นในเบราว์เซอร์ของคุณเบราว์เซอร์จะหยุดทำงานและคุณจะได้รับพรอมต์ให้ทำการดีบักรหัสการใช้งานจริง

อย่างไรก็ตามมีตัวเลือกอื่น ๆ (ฉันไม่แนะนำให้ทำ):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

แต่ขอแนะนำให้ดีบัก Python (pdb) สำหรับรหัส Python ทุกประเภท หากคุณอยู่ใน pdb แล้วคุณจะต้องดูที่IPDBที่ใช้ipythonสำหรับการดีบัก

ส่วนขยายที่เป็นประโยชน์ต่อ pdb คือ

PDB ++ , แนะนำโดยAntash

pudb , แนะนำโดยPatDuJour

ใช้ดีบักหลามใน Django , แนะนำโดยSeafangs


64
+1 สำหรับการแนะนำ pdb อย่างไรก็ตามมันน่าสังเกตว่ามันใช้งานได้จริงเมื่อใช้เซิร์ฟเวอร์การพัฒนาบนเครื่องของคุณเท่านั้นเนื่องจากพรอมต์จะปรากฏในคอนโซล
Daniel Roseman

12
ดูdjango-pdbตามคำตอบของฉันด้านล่าง ให้คุณmanage.py runserver --pdbและmanage.py test --pdbคำสั่ง
Tom Christie

4
@Daniel , ดูrconsoleสำหรับการมีคอนโซลเข้าสู่อินสแตนซ์ของ python ที่กำลังรันอยู่
Phob

12
ตรวจสอบipythonเช่นกัน Ipdbซึ่งมาพร้อมกับความipythonสมบูรณ์ของแท็บคุณสมบัติไวยากรณ์สีและอื่น ๆ :-)
hobbes3

3
ฉันพบว่าคำตอบของคุณมีประโยชน์ แต่ Django แขวนอยู่บนจุดพักของฉันตลอดไปเมื่อฉันพยายามที่จะทำการทดสอบ ดังนั้นฉันจึงค้นหาและพบบทความข้อมูลที่ช่วยฉันได้: v3.mike.tig.as/blog/2010/09/14/pdb
driftcatcher

228

ฉันชอบดีบักเกอร์แบบโต้ตอบของWerkzeugจริงๆ มันคล้ายกับหน้าดีบั๊กของ Django ยกเว้นว่าคุณได้รับเชลล์แบบโต้ตอบในทุกระดับของการสืบค้นกลับ หากคุณใช้django-extensionsคุณจะได้runserver_plusรับคำสั่งการจัดการซึ่งเริ่มต้นเซิร์ฟเวอร์การพัฒนาและให้ดีบักเกอร์ของ Werkzeug โดยมีข้อยกเว้น

แน่นอนคุณควรเรียกใช้ภายในเครื่องเท่านั้นเพราะจะให้สิทธิ์แก่ผู้ใช้งานในการเรียกใช้งานรหัสหลามตามอำเภอใจในบริบทของเซิร์ฟเวอร์


2
เป็นไปได้ไหมที่จะใช้การเติมข้อมูลด้วยแท็บในคอนโซลโต้ตอบที่แสดงในเบราว์เซอร์ "Tab" พาเราไปที่คอนโซลแบบเปิดถัดไปฉันสงสัยว่ามีคีย์ผสม แต่ฉันหาไม่เจอ
Ariel

@Ariel ดีบักเกอร์ werkzeug ไม่มีแท็บที่สมบูรณ์
Håken Lid

หากคุณกำลังดีบัก APIs คุณสามารถลองdjango-rundbgที่เพิ่มการบิดเล็กน้อยให้กับดีบักเกอร์ Werkzeug
elpaquete

มันขึ้นอยู่กับpython 3.3
Timo

ไม่รองรับช่องทางgithub.com/pallets/werkzeug/issues/1322
เปาโล

166

quickie เล็กน้อยสำหรับแท็กแม่แบบ:

@register.filter 
def pdb(element):
    import pdb; pdb.set_trace()
    return element

ในตอนนี้ภายในเทมเพลตที่คุณสามารถทำได้{{ template_var|pdb }}และเข้าสู่เซสชัน pdb (เนื่องจากคุณใช้เซิร์ฟเวอร์ devel ในพื้นที่) ซึ่งคุณสามารถตรวจสอบelementเนื้อหาของหัวใจได้

เป็นวิธีที่ดีมากในการดูว่าเกิดอะไรขึ้นกับวัตถุของคุณเมื่อมาถึงแม่แบบ


1
มันเยี่ยมมาก อีกสิ่งหนึ่งที่คุณสามารถทำได้หากคุณมีปัญหาแม่แบบคือเปลี่ยนเป็น jinja2 (โหลดผ่านโลงศพ) - เป็นส่วนเสริมของแม่แบบ django ซึ่งเป็นการปรับปรุงในความคิดของฉัน นอกจากนี้ยังรวมเทมเพลตและการสืบทอดเทมเพลตลงในเฟรมการติดตามย้อนกลับได้ดีกว่า django
fastmultiplication

นี่มันช่างน่ารัก น่าเสียดายที่มันยากที่จะเห็นวิธีที่สะอาดในการรวมสิ่งนี้เข้ากับ codebase ซึ่งปฏิเสธการกระทำใด ๆ รวมถึงการนำเข้า pdb
Jon Kiparsky

83

มีเครื่องมือบางอย่างที่ให้ความร่วมมือเป็นอย่างดีและสามารถทำให้งานการดีบักของคุณง่ายขึ้น

ที่สำคัญที่สุดคือการแก้ปัญหาแถบเครื่องมือ Django

แล้วคุณจะต้องเข้าสู่ระบบที่ดีโดยใช้งูหลามเข้าสู่ระบบสิ่งอำนวยความสะดวก คุณสามารถส่งผลผลิตเข้าสู่ระบบไปยังแฟ้มบันทึก แต่เป็นตัวเลือกที่ง่ายขึ้นจะส่งผลผลิตเข้าสู่ระบบเพื่อfirepython ในการใช้สิ่งนี้คุณต้องใช้เบราว์เซอร์ Firefox พร้อมกับส่วนเสริมfirebug Firepython มีปลั๊กอิน firebug ที่จะแสดงการบันทึกฝั่งเซิร์ฟเวอร์ในแท็บ Firebug

Firebug เองก็มีความสำคัญสำหรับการแก้ไขข้อบกพร่องด้าน Javascript ของแอพที่คุณพัฒนา (สมมติว่าคุณมีรหัส JS แน่นอน)

ฉันยังชอบdjango-viewtoolsสำหรับการดีบักมุมมองแบบโต้ตอบโดยใช้ pdb แต่ฉันไม่ได้ใช้มันมากนัก

มีเครื่องมือที่มีประโยชน์เช่น Dozer สำหรับติดตามการรั่วไหลของหน่วยความจำ


65

ฉันใช้PyCharm (เครื่องมือ pydev เดียวกันกับ eclipse) จริงๆช่วยให้ฉันสามารถมองเห็นขั้นตอนผ่านรหัสของฉันและดูสิ่งที่เกิดขึ้น


2
สิ่งที่ดีที่สุดเกี่ยวกับมันใช้งานได้และใช้งานง่ายโดยสิ้นเชิง เพียงคลิกทางด้านซ้ายของบรรทัดแล้วกดปุ่ม debug มันทำงานได้ดีสำหรับซอร์สโค้ด Django ด้วยหากคุณต้องการความเข้าใจที่ดีขึ้นเกี่ยวกับการทำงานของโค้ดภายใน ฉันใช้เวลาสักครู่ก่อนที่จะสังเกตเห็น แต่คุณสามารถใส่จุดพักในรหัสใด ๆ ในโฟลเดอร์ External Libraries ของเนวิเกเตอร์ไฟล์
Michael Bylstra

6
น่าจะพูดถึงว่า PyCharm ใช้ PyDev debugger ภายใต้ประทุนเพื่อรับเครดิต
Medeiros


44

เกือบทุกอย่างได้รับการกล่าวถึงแล้วดังนั้นฉันจะเพิ่มว่าแทนที่จะpdb.set_trace()สามารถใช้ipdb.set_trace ()ซึ่งใช้ iPython และดังนั้นจึงมีประสิทธิภาพมากขึ้น (เติมข้อความอัตโนมัติและสินค้าอื่น ๆ ) ต้องใช้แพ็คเกจ ipdb ดังนั้นคุณต้องpip install ipdb


2
ฉันแนะนำ pdb ++ ซึ่งให้โหมดเหนียวที่มีประโยชน์มาก
Sandeep

34

ผมเคยผลักดันdjango-pdbที่จะPyPI มันเป็นแอพที่เรียบง่ายซึ่งหมายความว่าคุณไม่จำเป็นต้องแก้ไขซอร์สโค้ดทุกครั้งที่คุณต้องการแบ่งเป็น pdb

การติดตั้งเป็นเพียง ...

  1. pip install django-pdb
  2. เพิ่ม'django_pdb'ของคุณINSTALLED_APPS

ตอนนี้คุณสามารถรัน: manage.py runserver --pdbเพื่อเจาะ pdb ในตอนเริ่มต้นของทุกมุมมอง ...

bash: manage.py runserver --pdb
Validating models...

0 errors found
Django version 1.3, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /
function "myview" in testapp/views.py:6
args: ()
kwargs: {}

> /Users/tom/github/django-pdb/testproject/testapp/views.py(7)myview()
-> a = 1
(Pdb)

และเรียกใช้: manage.py test --pdbแบ่งเป็น pdb ในการทดสอบความล้มเหลว / ข้อผิดพลาด ...

bash: manage.py test testapp --pdb
Creating test database for alias 'default'...
E
======================================================================
>>> test_error (testapp.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../django-pdb/testproject/testapp/tests.py", line 16, in test_error
    one_plus_one = four
NameError: global name 'four' is not defined
======================================================================

> /Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error()
-> one_plus_one = four
(Pdb)

โครงการที่โฮสต์บนGitHubยินดีรับการสนับสนุนแน่นอน


3
นี่จะดีมากถ้าคุณสามารถระบุหมายเลขไฟล์ / บรรทัดที่จะแตกที่ (ไม่ใช่แค่มุมมอง)
Anson MacKeracher

ที่ฉันสามารถทิ้งไว้ในรหัสเช่นความคิดเห็นที่มีความเฉื่อยในการผลิต บางทีนี่อาจเป็นกระบวนทัศน์ที่ไม่ดี แต่มันเป็นการดีที่จะตัดและใช้การแบ่งที่จำใจได้อย่างมีประสิทธิภาพ
Glycerine

ฉันเพิ่งติดตั้งสิ่งนี้เมื่อเร็ว ๆ นี้ แต่เฉพาะวันนี้คิดออกเพื่อกำหนดค่า "POST_MORTEM = True" ในการตั้งค่า dev ของฉันตามเอกสารโดย Tom's django-pdb ตอนนี้ฉันสามารถล่องเรือไปตามทางและเมื่อสิ่งต่าง ๆ แย่ลงฉันถูกทิ้งไปยังที่ตั้งของปัญหา ขอบคุณทอม!
โจเซฟ Sheedy

21

วิธีที่ง่ายที่สุดในการดีบัก python โดยเฉพาะสำหรับโปรแกรมเมอร์ที่ใช้กับ Visual Studio นั้นคือการใช้ PTVS (Python Tools สำหรับ Visual Studio) ขั้นตอนง่าย ๆ :

  1. ดาวน์โหลดและติดตั้งจากhttp://pytools.codeplex.com/
  2. ตั้งจุดพักและกด F5
  3. เบรกพอยต์ของคุณถูกโจมตีคุณสามารถดู / เปลี่ยนตัวแปรได้ง่ายเหมือนกับการดีบักโปรแกรม C # / C ++
  4. นั่นคือทั้งหมดที่ :)

หากคุณต้องการดีบัก Django โดยใช้ PTVS คุณต้องทำสิ่งต่อไปนี้:

  1. ในการตั้งค่าโครงการ - แท็บทั่วไปตั้ง "ไฟล์เริ่มต้น" เป็น "Manage.py" ซึ่งเป็นจุดเริ่มต้นของโปรแกรม Django
  2. ในการตั้งค่าโครงการ - แท็บดีบั๊กตั้ง "อาร์กิวเมนต์ของสคริปต์" เป็น "runserver - โหลดไม่โหลด" จุดสำคัญคือ "- โหลดไม่โหลด" ที่นี่ หากคุณไม่ได้ตั้งค่าจุดพักของคุณจะไม่ถูกโจมตี
  3. สนุกกับมัน.

1
ขอบคุณที่ใช้งานได้ดี --noreload เป็นสิ่งที่เราต้องการ
Tom Gruner

มีคุณสมบัติในการดีบักบนรีโมตเซิร์ฟเวอร์ - คล้ายกับ Eclipse PyDev ที่ฉันใช้ในตอนนี้หรือไม่?
Daniel Sokolowski

ฉันมีปัญหากับสิ่งนี้ ฉันทำตามขั้นตอนของคุณแล้ว แต่ก็ยังไม่ทำงาน มันจะหยุดในจุดพักของไฟล์ * .py ไม่ใช่ในไฟล์ * .html
blfuentes

16

ฉันใช้pyDevกับ Eclipse เป็นอย่างดีตั้งจุดพักขั้นตอนเป็นโค้ดดูค่าของวัตถุและตัวแปรลองดู


คุณต้องรันเซิร์ฟเวอร์ dev ผ่าน eclipse (สำหรับประสบการณ์การดีบักที่ใช้ความพยายามต่ำ) PyDev อ้างว่ามีการดีบักแบบรีโมท แต่ไม่เคยใช้มันฉันไม่สามารถพูดกับคุณภาพการพัฒนาได้ รายละเอียด: pydev.org/manual_adv_remote_debugger.html
synthesizerpatel

2
ดีบักเกอร์ระยะไกลของ PyDev ทำงานได้ค่อนข้างดีกับเซิร์ฟเวอร์ dev ของ Django เพียงให้แน่ใจว่าคุณมี "เมื่อไฟล์มีการเปลี่ยนแปลงโหลดโมดูลอัตโนมัติหรือไม่" ตัวเลือก '' disabled '' ในการตั้งค่า Run / Debug ของ PyDev มิฉะนั้นเซิร์ฟเวอร์ dev และ pydev จะพยายามโหลดรหัสซ้ำในขณะที่คุณกำลังดีบักซึ่งทำให้พวกเขาสับสนทั้งสองอย่างมาก
coredumperror

12

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

ฉันต้องบอกว่าPyCharmใช้หน่วยความจำมาก แต่แล้วอีกครั้งไม่มีอะไรดีในชีวิตฟรี พวกเขาเพิ่งมาพร้อมกับเวอร์ชันล่าสุด 3 และยังเล่นได้ดีมากกับ Django, Flask และ Google AppEngine ดังนั้นโดยสรุปฉันคิดว่ามันเป็นเครื่องมือที่ยอดเยี่ยมสำหรับนักพัฒนา

หากคุณยังไม่ได้ใช้งานฉันขอแนะนำให้ใช้เวอร์ชั่นทดลองเป็นเวลา 30 วันเพื่อดูพลังของ PyCharm ฉันแน่ใจว่ามีเครื่องมืออื่น ๆ เช่น Aptana แต่ฉันคิดว่าฉันก็ชอบวิธีที่ PyCharm ดู ฉันรู้สึกสบายใจในการดีบักแอพของฉันที่นั่น


อาจเป็น IDE แรกที่ฉันเคยซื้อ การดีบักโปรเจ็กต์ใน VM ดูเหมือนว่าน่าจะจ่ายเงิน
Rob Grant

10

บางครั้งเมื่อฉันต้องการสำรวจรอบ ๆ ในวิธีการเฉพาะและการเรียก pdb นั้นยุ่งยากเกินไปฉันจะเพิ่ม:

import IPython; IPython.embed()

IPython.embed() เริ่มต้น IPython shell ซึ่งสามารถเข้าถึงตัวแปรโลคัลจากจุดที่คุณเรียกใช้


ผมได้ทำนิสัยตอนนี้การทำเช่นนี้ที่ด้านบนของไฟล์และจากนั้นเมื่อใดก็ตามที่ฉันต้องการได้อย่างรวดเร็วเพิ่มเบรกพอยต์ในรหัสที่ผมเขียนfrom IPython import embed embed()ประหยัดเวลา เพื่อหลีกเลี่ยงการติดอยู่ในลูปตลอดไปฉันทำembed();exit();
Mayank Jaiswal

@ MayankJaiswal: ฉันมีการจับคู่คีย์ใน VIM เพื่อแทรกข้อมูลโค้ดนี้ (และตัวอย่างที่คล้ายกันสำหรับpudbและdebugger;ใน JavaScript) ลงในไฟล์ที่ฉันกำลังแก้ไข หลังจากที่ฉันทำฉันเพียงแค่dd(ลบทั้งบรรทัด) เพื่อลบเบรกพอยต์ วิธีนี้จะช่วยหลีกเลี่ยงความเสี่ยงในการยอมรับบรรทัดการนำเข้าดีบักเกอร์ในการควบคุมเวอร์ชันหรือต้องตั้งค่าการนำเข้าล่วงหน้าไว้ที่ด้านบนของไฟล์
โกหกที่

10

จากมุมมองของฉันเราสามารถแบ่งงานการดีบักรหัสทั่วไปออกเป็นสามรูปแบบการใช้งานที่แตกต่างกัน:

  1. มีข้อยกเว้นเกิดขึ้น : runserver_plus 'ดีบักเกอร์ Werkzeug เพื่อช่วยเหลือ ความสามารถในการเรียกใช้รหัสที่กำหนดเองในทุกระดับการติดตามคือตัวนักฆ่า และหากคุณติดขัดอย่างสมบูรณ์คุณสามารถสร้าง Gist เพื่อแชร์ด้วยการคลิกเพียงครั้งเดียว
  2. หน้าถูกแสดงผล แต่ผลลัพธ์ไม่ถูกต้อง : อีกครั้ง Werkzeug หิน ในการสร้างเบรกพอยต์ในรหัสเพียงพิมพ์assert Falseสถานที่ที่คุณต้องการหยุด
  3. โค้ดทำงานผิดปกติแต่รูปลักษณ์ที่รวดเร็วไม่ได้ช่วยอะไร อาจเป็นปัญหาอัลกอริทึม ถอนหายใจ แล้วฉันมักจะยิงขึ้นคอนโซลดีบักPuDBimport pudb; pudb.set_trace() : ข้อได้เปรียบที่สำคัญของ [i] pdb คือ PuDB (ในขณะที่มองคุณอยู่ในยุค 80) ทำให้การตั้งค่าการแสดงออกของนาฬิกาเป็นเรื่องง่าย และการดีบักพวงของลูปซ้อนกันนั้นง่ายกว่ามาก ๆ ด้วย GUI

อ๊ะใช่ความทุกข์ของแม่แบบ ปัญหาที่พบบ่อยที่สุด (สำหรับฉันและเพื่อนร่วมงาน) เป็นบริบทที่ไม่ถูกต้อง: คุณไม่มีตัวแปรหรือตัวแปรของคุณไม่มีคุณลักษณะบางอย่าง หากคุณใช้แถบเครื่องมือดีบั๊กเพียงตรวจสอบบริบทที่ส่วน "เทมเพลต" หรือหากไม่เพียงพอให้กำหนดตัวแบ่งในโค้ดมุมมองของคุณหลังจากเติมบริบทเสร็จแล้ว

ดังนั้นมันจะไป


พิมพ์ให้น้อยลงโดยใช้เพียงimport pudb;pu.db
Sławomir Lenart

6

ฉันขอแนะนำ epdb (Extended Python Debugger)

https://bitbucket.org/dugan/epdb

สิ่งหนึ่งที่ฉันชอบเกี่ยวกับ epdb สำหรับการดีบัก Django หรือ Python webservers อื่น ๆ คือคำสั่ง epdb.serve () ชุดนี้เป็นการติดตามและให้บริการสิ่งนี้บนโลคัลพอร์ตที่คุณสามารถเชื่อมต่อได้ กรณีการใช้งานทั่วไป:

ฉันมีมุมมองที่ฉันต้องการทำทีละขั้นตอน ฉันจะแทรกสิ่งต่อไปนี้ ณ จุดที่ฉันต้องการตั้งค่าการติดตาม

import epdb; epdb.serve()

เมื่อโค้ดนี้ถูกประมวลผลฉันเปิดล่าม Python และเชื่อมต่อกับอินสแตนซ์การให้บริการ ฉันสามารถวิเคราะห์ค่าและขั้นตอนทั้งหมดผ่านรหัสโดยใช้คำสั่ง pdb มาตรฐานเช่น n, s, ฯลฯ

In [2]: import epdb; epdb.connect()
(Epdb) request
<WSGIRequest
path:/foo,
GET:<QueryDict: {}>, 
POST:<QuestDict: {}>,
...
>
(Epdb) request.session.session_key
'i31kq7lljj3up5v7hbw9cff0rga2vlq5'
(Epdb) list
 85         raise some_error.CustomError()
 86 
 87     # Example login view
 88     def login(request, username, password):
 89         import epdb; epdb.serve()
 90  ->     return my_login_method(username, password)
 91
 92     # Example view to show session key
 93     def get_session_key(request):
 94         return request.session.session_key
 95

และอีกมากมายที่คุณสามารถเรียนรู้เกี่ยวกับการพิมพ์ epdb help ได้ตลอดเวลา

หากคุณต้องการให้บริการหรือเชื่อมต่อกับอินสแตนซ์ epdb หลายตัวในเวลาเดียวกันคุณสามารถระบุพอร์ตที่จะรับฟังได้ (ค่าเริ่มต้นคือ 8080) กล่าวคือ

import epdb; epdb.serve(4242)

>> import epdb; epdb.connect(host='192.168.3.2', port=4242)

โฮสต์เริ่มต้นที่ 'localhost' หากไม่ได้ระบุ ฉันโยนมันลงที่นี่เพื่อสาธิตวิธีที่คุณสามารถใช้สิ่งนี้เพื่อดีบักอย่างอื่นนอกเหนือจากอินสแตนซ์ในพื้นที่เช่นเซิร์ฟเวอร์การพัฒนาบน LAN ท้องถิ่นของคุณ เห็นได้ชัดว่าถ้าคุณทำเช่นนี้โปรดระวังว่าชุดการติดตามจะไม่ทำให้เกิดขึ้นบนเซิร์ฟเวอร์ที่ใช้งานจริงของคุณ!

เพื่อทราบอย่างรวดเร็วคุณยังสามารถทำสิ่งเดียวกันกับคำตอบที่ยอมรับกับ epdb ( import epdb; epdb.set_trace()) แต่ฉันต้องการเน้นฟังก์ชั่นการให้บริการเนื่องจากฉันพบว่ามันมีประโยชน์มาก


epdb ไม่ได้รับการอัปเดตตั้งแต่ปี 2011 คุณเคยประสบปัญหาในการใช้กับ Django และ / หรือ Python เวอร์ชั่นใหม่กว่าหรือไม่?
Seperman

ฉันไม่เคยพบปัญหาในการใช้กับ Python 2 (โดยเฉพาะ 2.4-2.7) ฉันใช้มันเมื่อไม่กี่วันที่ผ่านมาจริงๆแล้ว ฉันไม่เคยลองกับ Python 3
Jacinda

1
ฉันใช้ django 1.8 บน python 2.7 และไม่สามารถรับ epdb.connect เพื่อคุยกับ epdb.serve ฉันเพิ่งหมดเวลา
David Watson

6

ฉันเพิ่งพบ wdb ( http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401 ) มันมีอินเทอร์เฟซผู้ใช้ที่ดี / GUI กับ bells และ whistles ทั้งหมด ผู้เขียนบอกสิ่งนี้เกี่ยวกับ wdb -

"มี IDEs อย่าง PyCharm ที่มี debuggers เป็นของตัวเองพวกเขามีคุณสมบัติที่คล้ายกันหรือเท่ากัน ... อย่างไรก็ตามคุณต้องใช้ IDE เหล่านั้นโดยเฉพาะ (และบางอันก็ไม่เป็นอิสระหรืออาจไม่สามารถใช้ได้สำหรับทุกคน แพลตฟอร์ม) เลือกเครื่องมือที่เหมาะสมกับความต้องการของคุณ "

คิดว่าฉันจะผ่านมันไป

บทความที่มีประโยชน์มากเกี่ยวกับตัวแก้ข้อบกพร่องของหลาม: https://zapier.com/engineering/debugging-python-boss/

สุดท้ายถ้าคุณต้องการที่จะเห็นผลงานพิมพ์กราฟิกที่ดีของสแต็คโทรของคุณใน Django ชำระเงิน: https://github.com/joerick/pyinstrument เพียงเพิ่ม pyinstrument.middleware.ProfilerMiddleware ไปยัง MIDDLEWARE_CLASSES แล้วเพิ่ม? profile ที่ส่วนท้ายของ URL คำขอเพื่อเปิดใช้งาน profiler

ยังสามารถเรียกใช้ pyinstrument จากบรรทัดคำสั่งหรือโดยการนำเข้าเป็นโมดูล


PyCharm ใช้ PyDev ฉันคิดว่าไม่ใช่ของตัวเอง
Rob Grant

6

เพิ่มimport pdb; pdb.set_trace()หรือbreakpoint() (form python3.7)ที่บรรทัดที่เกี่ยวข้องในรหัส Python และดำเนินการ การดำเนินการจะหยุดด้วยเชลล์แบบโต้ตอบ ในเชลล์คุณสามารถรันโค้ด Python (เช่นตัวแปรการพิมพ์) หรือใช้คำสั่งเช่น:

  • c ดำเนินการต่อไป
  • n ขั้นตอนไปยังบรรทัดถัดไปภายในฟังก์ชั่นเดียวกัน
  • s ก้าวไปยังบรรทัดถัดไปในฟังก์ชั่นนี้หรือฟังก์ชั่นที่เรียกว่า
  • q ออกจากดีบักเกอร์ / การดำเนินการ

ดูเพิ่มเติมที่: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28


5

หนึ่งในตัวเลือกที่ดีที่สุดในการดีบักโค้ด Django คือผ่าน wdb: https://github.com/Kozea/wdb

wdb ทำงานได้กับ python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) และ pypy ยิ่งไปกว่านั้นมันเป็นไปได้ที่จะดีบั๊กโปรแกรมไพ ธ อน 2 ด้วยเซิร์ฟเวอร์ wdb ที่ทำงานบนไพ ธ อน 3 และในทางกลับกันหรือดีบั๊กโปรแกรมที่ทำงานบนคอมพิวเตอร์ที่มีเซิร์ฟเวอร์ดีบั๊กทำงานบนคอมพิวเตอร์เครื่องอื่นภายในเว็บเพจบนคอมพิวเตอร์เครื่องที่สาม! ยิ่งไปกว่านั้นตอนนี้คุณสามารถหยุดกระบวนการไพ ธ อน / เธรดที่กำลังรันอยู่ชั่วคราวโดยใช้การฉีดโค้ดจากเว็บอินเตอร์เฟส (ต้องเปิดใช้งาน gdb และ ptrace) กล่าวอีกนัยหนึ่งคือ pdb รุ่นที่ปรับปรุงแล้วโดยตรงในเบราว์เซอร์ของคุณพร้อมคุณสมบัติที่ดี

ติดตั้งและเรียกใช้เซิร์ฟเวอร์และในรหัสของคุณเพิ่ม:

import wdb
wdb.set_trace()

ตามที่ผู้เขียนความแตกต่างที่สำคัญด้วยความเคารพpdbคือ:

สำหรับผู้ที่ไม่ทราบว่าโครงการ wdb เป็นตัวแก้จุดบกพร่องหลามอย่าง pdb แต่มีหน้าเว็บเรียบเนียนและมีคุณสมบัติเพิ่มเติมมากมายเช่น:

  • การเน้นไวยากรณ์ต้นฉบับ
  • จุดพักการมองเห็น
  • การเติมโค้ดแบบโต้ตอบโดยใช้เจได
  • จุดพักถาวร
  • การตรวจสอบวัตถุที่ลึกโดยใช้เมาส์รองรับการทำงานมัลติเธรด / มัลติโปรเซสเซอร์
  • การดีบักระยะไกล
  • รับชมการแสดงออก
  • ในรุ่นรหัสดีบักเกอร์
  • การรวมเว็บเซิร์ฟเวอร์ยอดนิยมเพื่อแก้ไขข้อผิดพลาด
  • ยกเว้นการแตกระหว่างการติดตาม (ไม่ใช่การโพสต์ชันสูตร) ​​ในทางตรงกันข้ามกับดีบักเกอร์ werkzeug เป็นต้น
  • ทำลายโปรแกรมที่รันอยู่ในปัจจุบันผ่านการฉีดรหัส (บนระบบที่รองรับ)

มันมีส่วนต่อประสานผู้ใช้ที่เยี่ยมยอด ความสุขที่จะใช้! :)


ความแตกต่างกับ pdb คืออะไร?
Dunatotatos

4

ฉันใช้PyCharmและเครื่องมือตรวจแก้จุดบกพร่องต่าง ๆ นอกจากนี้ยังมีบทความที่ดีตั้งค่าเกี่ยวกับเรื่องง่ายตั้งค่าสิ่งเหล่านั้นสำหรับมือใหม่ คุณอาจเริ่มที่นี่ มันบอกเกี่ยวกับการดีบัก PDB และ GUI โดยทั่วไปกับโครงการ Django หวังว่าใครบางคนจะได้ประโยชน์จากพวกเขา



2

ตัวเลือกส่วนใหญ่จะกล่าวถึง alredy ในการพิมพ์บริบทเทมเพลตฉันได้สร้างไลบรารีอย่างง่ายสำหรับสิ่งนั้น ดูhttps://github.com/edoburu/django-debugtools

คุณสามารถใช้มันเพื่อพิมพ์บริบทเทมเพลตโดยไม่มี{% load %}โครงสร้างใด ๆ:

{% print var %}   prints variable
{% print %}       prints all

มันใช้รูปแบบ pprint ที่กำหนดเองเพื่อแสดงตัวแปรใน<pre>แท็ก


2

ฉันพบว่า Visual Studio Code ยอดเยี่ยมสำหรับการแก้ไขข้อบกพร่องของแอป Django พารามิเตอร์ python launch.json มาตรฐานทำงานpython manage.pyด้วย debugger ที่แนบมาดังนั้นคุณสามารถกำหนดจุดพักและก้าวผ่านโค้ดของคุณได้ตามต้องการ


2

สำหรับผู้ที่สามารถเพิ่ม pdb โดยไม่ตั้งใจลงในการแสดงสดฉันสามารถแนะนำส่วนขยายของ #Koobz คำตอบนี้:

@register.filter 
def pdb(element):
    from django.conf import settings
    if settings.DEBUG:    
        import pdb
        pdb.set_trace()
    return element

2

จากประสบการณ์ของฉันมีสองทาง:

  1. ใช้ipdbซึ่งเป็น debugger ที่ปรับปรุงแล้วจะชอบ pdb

    import ipdb;ipdb.set_trace()หรือbreakpoint() (จาก python3.7)

  2. ใช้เปลือก django เพียงใช้คำสั่งด้านล่าง นี่เป็นประโยชน์อย่างมากเมื่อคุณพัฒนามุมมองใหม่

    python manage.py shell


1

ฉันขอแนะนำให้ใช้ PDB

import pdb
pdb.set_trace()

คุณสามารถตรวจสอบค่าตัวแปรทั้งหมดเข้าสู่ฟังก์ชันและอีกมากมาย https://docs.python.org/2/library/pdb.html

สำหรับการตรวจสอบคำขอการตอบสนองและการเข้าถึงฐานข้อมูลทุกประเภทฉันใช้ django-debug-toolbar https://github.com/django-debug-toolbar/django-debug-toolbar


1

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

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

นอกจากนี้ฉันใช้ PyCharm - มันมีการวิเคราะห์โค้ดคงที่ที่ยอดเยี่ยมและสามารถช่วยตรวจสอบปัญหาก่อนที่คุณจะรู้ว่ามี

ดังกล่าวแล้ว django-debug-toolbar เป็นสิ่งจำเป็น - https://github.com/django-debug-toolbar/django-debug-toolbar

และในขณะที่ไม่ใช่เครื่องมือตรวจแก้จุดบกพร่องหรือการวิเคราะห์ - หนึ่งในรายการโปรดของฉันคือSQL Printing Middlewareจาก Django Snippets ที่https://djangosnippets.org/snippets/290/

นี่จะแสดงคิวรี SQL ที่มุมมองของคุณสร้างขึ้น สิ่งนี้จะช่วยให้คุณเข้าใจว่า ORM กำลังทำอะไรและหากแบบสอบถามของคุณมีประสิทธิภาพหรือคุณจำเป็นต้องทำงานซ้ำรหัสของคุณ (หรือเพิ่มแคช)

ฉันพบว่ามันมีค่ามากสำหรับการจับตาดูประสิทธิภาพของคิวรีในขณะที่พัฒนาและแก้ไขข้อบกพร่องแอปพลิเคชันของฉัน

เคล็ดลับอีกข้อหนึ่ง - ฉันแก้ไขมันเล็กน้อยเพื่อใช้เองเพื่อแสดงข้อมูลสรุปเท่านั้นไม่ใช่คำสั่ง SQL .... ดังนั้นฉันจึงใช้มันในขณะที่กำลังพัฒนาและทดสอบอยู่เสมอ ฉันยังเพิ่มว่าถ้า len (connection.queries) มากกว่าขีด จำกัด ที่กำหนดไว้ล่วงหน้าจะแสดงคำเตือนเพิ่มเติม

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


1

ใช้หรือpdb ipdbความแตกต่างระหว่างสองสิ่งนี้คือ ipdb รองรับการทำให้สมบูรณ์อัตโนมัติ

สำหรับ pdb

import pdb
pdb.set_trace()

สำหรับ ipdb

import ipdb
ipdb.set_trace()

สำหรับการดำเนินการกดปุ่มสายใหม่สำหรับการกดnปุ่มต่อcไป ตรวจสอบตัวเลือกเพิ่มเติมโดยใช้help(pdb)


0

ข้อเสนอแนะเพิ่มเติม

คุณสามารถใช้ประโยชน์จากnosetestsและpdbร่วมกันแทนที่จะฉีดpdb.set_trace()ในมุมมองของคุณด้วยตนเอง ข้อดีคือคุณสามารถสังเกตเงื่อนไขข้อผิดพลาดเมื่อพวกเขาเริ่มแรกอาจในรหัสบุคคลที่สาม

นี่เป็นข้อผิดพลาดสำหรับฉันวันนี้

TypeError at /db/hcm91dmo/catalog/records/

render_option() argument after * must be a sequence, not int

....


Error during template rendering

In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28
render_option() argument after * must be a sequence, not int
18  
19          {% if field|is_checkboxselectmultiple %}
20              {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21          {% endif %}
22  
23          {% if field|is_radioselect %}
24              {% include 'bootstrap3/layout/radioselect.html' %}
25          {% endif %}
26  
27          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28  

      {% if field|is_checkbox and form_show_labels %}

ตอนนี้ฉันรู้ว่านี่หมายความว่าฉันทำตัวสร้างคอนสตรัคเตอร์สำหรับแบบฟอร์มและฉันก็มีความคิดที่ดีว่าฟิลด์ใดเป็นปัญหา แต่ฉันสามารถใช้ pdb เพื่อดูว่าแบบฟอร์มกรอบที่บ่นเกี่ยวกับภายในแม่แบบได้หรือไม่

ใช่ฉันทำได้. ใช้ตัวเลือก--pdbใน nosetests:

tests$ nosetests test_urls_catalog.py --pdb

ทันทีที่ฉันกดข้อยกเว้นใด ๆ (รวมถึงรายการที่จัดการอย่างงดงาม), pdb หยุดที่มันเกิดขึ้นและฉันสามารถมองไปรอบ ๆ

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 537, in __str__
    return self.as_widget()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 593, in as_widget
    return force_text(widget.render(name, self.value(), attrs=attrs))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 513, in render
    options = self.render_options(choices, [value])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 543, in render_options
    output.append(self.render_option(selected_choices, *option))
TypeError: render_option() argument after * must be a sequence, not int
INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html)
INFO lib.capture_middleware log write_to_index:end
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py(543)render_options()
-> output.append(self.render_option(selected_choices, *option))
(Pdb) import pprint
(Pdb) pprint.PrettyPrinter(indent=4).pprint(self)
<django.forms.widgets.Select object at 0x115fe7d10>
(Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self))
{   'attrs': {   'class': 'select form-control'},
    'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]],
    'is_required': False}
(Pdb)         

ตอนนี้เป็นที่ชัดเจนว่าตัวเลือกของฉันโต้แย้งกับตัวสร้างเขตข้อมูลที่กรอบเป็นเพราะมันเป็นรายการภายในรายการแทนที่จะเป็นรายการ / tuple ของสิ่งอันดับ

 'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]

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


0

ในระหว่างการพัฒนาเพิ่มอย่างรวดเร็ว

assert False, value

สามารถช่วยวินิจฉัยปัญหาในมุมมองหรือที่อื่น ๆ โดยไม่จำเป็นต้องใช้ดีบักเกอร์

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