Làm thế nào để gỡ lỗi trong Django, cách tốt? [đóng cửa]


587

Vì vậy, tôi bắt đầu học viết mã bằng Python và sau đó là Django . Lần đầu tiên, thật khó để nhìn vào tracebacks và thực sự tìm ra những gì tôi đã làm sai và lỗi cú pháp ở đâu. Một thời gian đã trôi qua và một lúc nào đó, tôi đoán rằng tôi có một thói quen trong việc gỡ lỗi mã Django. Vì điều này đã được thực hiện sớm trong trải nghiệm mã hóa của tôi, tôi ngồi xuống và tự hỏi liệu làm thế nào tôi làm điều này là không hiệu quả và có thể được thực hiện nhanh hơn. Tôi thường quản lý để tìm và sửa các lỗi trong mã của mình, nhưng tôi tự hỏi liệu tôi có nên làm điều đó nhanh hơn không?

Tôi thường chỉ sử dụng thông tin gỡ lỗi mà Django cung cấp khi được bật. Khi mọi thứ kết thúc như tôi nghĩ, tôi sẽ phá vỡ dòng mã rất nhiều với lỗi cú pháp và xem xét các biến tại điểm đó trong luồng để tìm ra, nơi mã làm điều gì đó ngoài những gì tôi muốn.

Nhưng điều này có thể được cải thiện? Có một số công cụ tốt hoặc cách tốt hơn để gỡ lỗi mã Django của bạn?


2
Tôi thích sử dụng django-debug-thanh công cụ, nó rất tiện dụng
Diego Vinícius

1
Hoặc sử dụng trình gỡ lỗi Python tích hợp trong Visual Studio Code như được giải thích ở đây code.visualstudio.com/docs/python/tutorial-django
Nick T

Câu trả lời:


536

Có rất nhiều cách để làm điều đó, nhưng đơn giản nhất là chỉ cần sử dụng trình gỡ lỗi Python . Chỉ cần thêm dòng sau vào chức năng xem Django:

import pdb; pdb.set_trace()

hoặc là

breakpoint()  #from Python3.7

Nếu bạn cố tải trang đó trong trình duyệt của mình, trình duyệt sẽ bị treo và bạn nhận được lời nhắc tiếp tục gỡ lỗi trên mã thực thi thực tế.

Tuy nhiên, có những lựa chọn khác (tôi không khuyến nghị chúng):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

Nhưng Trình gỡ lỗi Python (pdb) rất được khuyến nghị cho tất cả các loại mã Python. Nếu bạn đã vào pdb, bạn cũng muốn xem IPDB sử dụng ipython để gỡ lỗi.

Một số tiện ích mở rộng hữu ích hơn cho pdb là

pdb ++ , được đề xuất bởi Antash .

pudb , được đề xuất bởi PatDuJour .

Sử dụng trình gỡ lỗi Python trong Django , được đề xuất bởi Sea Phường .


64
+1 để đề xuất pdb. Tuy nhiên, điều đáng chú ý là điều này chỉ thực sự hoạt động khi sử dụng máy chủ phát triển trên máy cục bộ của bạn, vì lời nhắc sẽ xuất hiện trong bảng điều khiển.
Daniel Roseman

12
Xem thêm django-pdb theo câu trả lời của tôi dưới đây. Cung cấp cho bạn manage.py runserver --pdbmanage.py test --pdblệnh.
Tom Christie

4
@Daniel , xem rconsole để có bàn điều khiển vào một phiên bản đã chạy của python.
Phob

12
Kiểm tra ipythonlà tốt. Ipdb, đi kèm ipython, tính năng hoàn thành tab, cú pháp màu và hơn thế nữa :-).
hobbes3

3
Tôi thấy câu trả lời của bạn hữu ích nhưng Django đã bị treo mãi mãi trên các điểm dừng của tôi, khi tôi đang cố gắng gỡ lỗi một bài kiểm tra. Vì vậy, tôi đã xem và tìm thấy một bài viết thông tin giúp tôi: v3.mike.tig.as/blog/2010/09/14/pdb
driftcatcher

228

Tôi thực sự thích trình gỡ lỗi tương tác của Werkzeug . Nó tương tự như trang gỡ lỗi của Django, ngoại trừ việc bạn có được lớp vỏ tương tác ở mọi cấp độ của truy nguyên. Nếu bạn sử dụng phần mở rộng django , bạn sẽ nhận được runserver_pluslệnh quản lý khởi động máy chủ phát triển và cung cấp cho bạn trình gỡ lỗi của Werkzeug về các ngoại lệ.

Tất nhiên, bạn chỉ nên chạy cái này cục bộ, vì nó cung cấp cho bất kỳ ai có trình duyệt quyền thực thi mã python tùy ý trong ngữ cảnh của máy chủ.


2
Có thể sử dụng hoàn thành tab trong bảng điều khiển tương tác được hiển thị trong trình duyệt không? "Tab" chỉ đưa chúng ta đến bảng điều khiển mở tiếp theo, tôi tự hỏi liệu có một tổ hợp phím nào không, nhưng tôi không thể tìm thấy.
Ariel

@Ariel trình gỡ lỗi werkzeug không hoàn thành tab.
Håken Nắp

Nếu bạn đang gỡ lỗi API, bạn có thể thử django-rundbg có thêm một chút thay đổi cho trình gỡ lỗi Werkzeug.
elpaquete

Nó chỉ tối đapython 3.3
Timo

không hỗ trợ các kênh truyền hình github.com/pallets/werkzeug/issues/1322
Paolo

166

Một chút quickie cho các thẻ mẫu:

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

Bây giờ, bên trong một mẫu bạn có thể làm {{ template_var|pdb }}và nhập phiên pdb (với điều kiện bạn đang chạy máy chủ phát cục bộ) nơi bạn có thể kiểm tra elementnội dung trái tim của mình.

Đó là một cách rất hay để xem những gì đã xảy ra với đối tượng của bạn khi nó đến mẫu.


1
điều đó thật tuyệt. Một điều khác bạn có thể làm nếu bạn gặp vấn đề về mẫu là chuyển sang jinja2 (được tải qua quan tài) - đó là một phần mở rộng của các mẫu django, theo quan điểm của tôi. Nó cũng tích hợp các mẫu và kế thừa mẫu vào các khung theo dõi tốt hơn so với django.
fastmultiplication

Cái này thật đáng yêu. Thật không may, thật khó để thấy một cách rõ ràng để tích hợp điều này vào một cơ sở mã mà từ chối mọi cam kết bao gồm cả việc nhập pdb.
Jon Kiparsky

83

Có một vài công cụ hợp tác tốt và có thể làm cho công việc sửa lỗi của bạn dễ dàng hơn.

Quan trọng nhất là thanh công cụ gỡ lỗi Django .

Sau đó, bạn cần đăng nhập tốt bằng cách sử dụng tiện ích ghi nhật ký Python . Bạn có thể gửi đầu ra đăng nhập đến một tệp nhật ký, nhưng một tùy chọn dễ dàng hơn là gửi đầu ra nhật ký đến firepython . Để sử dụng điều này, bạn cần sử dụng trình duyệt Firefox với phần mở rộng firebird . Firepython bao gồm một plugin Firebird sẽ hiển thị bất kỳ nhật ký phía máy chủ nào trong tab Fireorms.

Bản thân Firebug cũng rất quan trọng trong việc gỡ lỗi phía Javascript của bất kỳ ứng dụng nào bạn phát triển. (Giả sử bạn có một số mã JS tất nhiên).

Tôi cũng thích django-viewtools để gỡ lỗi các khung nhìn tương tác bằng pdb, nhưng tôi không sử dụng nó nhiều.

Có nhiều công cụ hữu ích hơn như dozer để theo dõi rò rỉ bộ nhớ (cũng có những gợi ý hay khác được đưa ra trong câu trả lời ở đây trên SO để theo dõi bộ nhớ).


65

Tôi sử dụng PyCharm (cùng động cơ pydev như nhật thực). Thực sự giúp tôi trực quan có thể bước qua mã của tôi và xem những gì đang xảy ra.


2
Điều tốt nhất về nó là nó chỉ hoạt động và hoàn toàn trực quan. Chỉ cần nhấp vào bên trái của một dòng và nhấn nút gỡ lỗi. Nó cũng hoạt động tốt cho mã nguồn Django nếu bạn muốn hiểu rõ hơn về cách thức hoạt động của mã nội bộ. Phải mất một lúc trước khi tôi nhận thấy nó, nhưng bạn có thể đặt các điểm dừng trong bất kỳ mã nào trong thư mục Thư viện bên ngoài của trình điều hướng tệp.
Michael Bylstra

6
Đáng nói là PyCharm sử dụng trình gỡ lỗi PyDev dưới mui xe cho các khoản tín dụng.
Medeiros


44

Hầu như mọi thứ đã được đề cập cho đến nay, vì vậy tôi sẽ chỉ thêm rằng thay vì pdb.set_trace()người ta có thể sử dụng ipdb.set_trace () sử dụng iPython và do đó mạnh hơn (tự động hoàn thành và các tính năng khác). Điều này đòi hỏi gói ipdb, vì vậy bạn chỉ cầnpip install ipdb


2
Tôi khuyên bạn nên pdb ++ cung cấp chế độ dính rất hữu ích.
Sandeep

34

Tôi đã bị đẩy django-pdbđến PyPI . Đây là một ứng dụng đơn giản có nghĩa là bạn không cần chỉnh sửa mã nguồn mỗi khi bạn muốn đột nhập vào pdb.

Cài đặt chỉ là ...

  1. pip install django-pdb
  2. Thêm 'django_pdb'vào của bạnINSTALLED_APPS

Bây giờ bạn có thể chạy: manage.py runserver --pdbđể xâm nhập vào pdb khi bắt đầu mọi chế độ xem ...

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)

Và chạy: manage.py test --pdbđể đột nhập vào pdb khi lỗi / lỗi kiểm tra ...

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)

Dự án được lưu trữ trên GitHub , tất nhiên các đóng góp đều được chào đón.


3
Điều này sẽ rất tuyệt nếu bạn có thể chỉ định số tệp / dòng để ngắt tại (không chỉ là dạng xem).
Anson MacKeracher

Tôi có thể để lại mã như những bình luận trơ trong sản xuất. Có lẽ đây là một thiên đường tồi tệ, nhưng sẽ rất tuyệt nếu lột đồ một cách hiệu quả và áp dụng các biện pháp phá vỡ willy-nilly.
Glycerine

Tôi đã cài đặt cái này gần đây, nhưng chỉ hôm nay mới tìm ra cấu hình "POST_MORTEM = True" trong cài đặt dev của tôi như được tài liệu bởi Tom's django-pdb. Bây giờ tôi chỉ có thể đi tàu dọc và khi mọi thứ trở nên tồi tệ, tôi rơi ngay vào vị trí của vấn đề. Cảm ơn Tom!
Joseph Sheedy

21

Cách dễ nhất để gỡ lỗi python - đặc biệt đối với các lập trình viên đã quen với Visual Studio - là sử dụng PTVS (Công cụ Python cho Visual Studio). Các bước rất đơn giản:

  1. Tải xuống và cài đặt nó từ http://pytools.codeplex.com/
  2. Đặt điểm dừng và nhấn F5.
  3. Điểm dừng của bạn bị tấn công, bạn có thể xem / thay đổi các biến dễ dàng như gỡ lỗi các chương trình C # / C ++.
  4. Đó là tất cả :)

Nếu bạn muốn gỡ lỗi Django bằng PTVS, bạn cần làm như sau:

  1. Trong Cài đặt dự án - Tab Chung, đặt "Tệp khởi động" thành "Manage.py", điểm vào của chương trình Django.
  2. Trong cài đặt Dự án - tab Gỡ lỗi, đặt "Đối số tập lệnh" thành "máy chủ --noreload". Điểm mấu chốt là "--noreload" ở đây. Nếu bạn không đặt nó, điểm dừng của bạn sẽ không bị ảnh hưởng.
  3. Hãy tận hưởng nó.

1
Cảm ơn, điều đó đã làm việc tuyệt vời. --Noreload là những gì chúng ta cần
Tom Gruner

Có một tính năng để gỡ lỗi trên máy chủ từ xa - tương tự như Eclipse PyDev mà tôi sử dụng hiện tại không?
Daniel Sokolowski

Tôi đang gặp vấn đề với điều này. Tôi đã làm theo các bước của bạn nhưng vẫn không làm việc. Nó chỉ dừng lại ở các điểm dừng của các tệp * .py, không dừng ở các tệp * .html.
blfuentes

16

Tôi sử dụng pyDev với Eclipse thực sự tốt, đặt các điểm ngắt, bước vào mã, xem các giá trị trên bất kỳ đối tượng và biến nào, hãy thử nó.


Bạn phải chạy máy chủ dev thông qua nhật thực (đối với trải nghiệm gỡ lỗi với nỗ lực thấp). PyDev tuyên bố đã gỡ lỗi từ xa nhưng chưa bao giờ sử dụng nó, tôi thực sự không thể nói đến chất lượng của trải nghiệm phát triển. Chi tiết: pydev.org/manual_adv_remote_debugger.html
tổng

2
Trình gỡ lỗi từ xa của PyDev hoạt động khá tuyệt vời với máy chủ dev của Django. Chỉ cần đảm bảo rằng bạn có "Khi tệp được thay đổi, tự động tải lại mô-đun?" tùy chọn '' bị vô hiệu hóa 'trong cài đặt Chạy / Gỡ lỗi của PyDev. Nếu không, máy chủ dev và pydev đều sẽ cố tải lại mã trong khi bạn gỡ lỗi, điều này khiến cả hai vô cùng bối rối.
coredumperror

12

Tôi sử dụng PyCharmluôn sẵn sàng . Nó làm tôi tốn kém một chút nhưng tôi phải nói lợi thế mà tôi có được từ nó là vô giá. Tôi đã thử gỡ lỗi từ bảng điều khiển và tôi cung cấp cho mọi người rất nhiều tín dụng có thể làm điều đó, nhưng đối với tôi có thể gỡ lỗi trực quan (các) ứng dụng của tôi thì thật tuyệt.

Tôi phải nói rằng, PyCharm chiếm rất nhiều bộ nhớ. Nhưng sau đó, một lần nữa, không có gì tốt là miễn phí trong cuộc sống. Họ chỉ đi kèm với phiên bản mới nhất 3. Nó cũng chơi rất tốt với Django, Flask và Google AppEngine. Vì vậy, tất cả trong tất cả, tôi muốn nói rằng đó là một công cụ tiện dụng tuyệt vời cần có cho bất kỳ nhà phát triển nào.

Nếu bạn chưa sử dụng nó, tôi khuyên bạn nên dùng phiên bản dùng thử trong 30 ngày để xem sức mạnh của PyCharm. Tôi chắc chắn có những công cụ khác cũng có sẵn, chẳng hạn như Aptana. Nhưng tôi đoán tôi cũng thích vẻ ngoài của PyCharm. Tôi cảm thấy rất thoải mái khi gỡ lỗi các ứng dụng của tôi ở đó.


Nó có thể là IDE đầu tiên tôi từng mua. Gỡ lỗi một dự án trong VM nghe có vẻ kỳ diệu đáng để trả tiền.
Rob Grant

10

Đôi khi, khi tôi muốn khám phá xung quanh trong một phương thức cụ thể và việc triệu tập pdb quá phức tạp, tôi sẽ thêm:

import IPython; IPython.embed()

IPython.embed() bắt đầu một vỏ IPython có quyền truy cập vào các biến cục bộ từ điểm bạn gọi nó.


Bây giờ tôi đã tạo thói quen để làm điều này ở đầu tệp from IPython import embedvà sau đó bất cứ khi nào tôi muốn nhanh chóng thêm một điểm dừng trong mã, tôi viết embed(). Tiết kiệm thời gian. Để tránh bị mắc kẹt trong các vòng lặp mãi mãi, tôi làmembed();exit();
Mayank Jaiswal

@MayankJaiswal: Tôi đã có một ánh xạ chính trên Vim để chèn đoạn mã này (và các đoạn tương tự cho pudbdebugger;trong JavaScript) vào tệp tôi đang chỉnh sửa. Sau khi xong, tôi chỉ dd(xóa toàn bộ dòng) để xóa điểm dừng. Điều này tránh rủi ro khi đưa dòng nhập trình gỡ lỗi vào kiểm soát phiên bản hoặc phải đặt trước việc nhập trước ở đầu tệp.
Lie Ryan

10

Từ quan điểm của tôi, chúng ta có thể chia các tác vụ gỡ lỗi mã phổ biến thành ba kiểu sử dụng riêng biệt:

  1. Một cái gì đó đã nêu ra một ngoại lệ : runserver_plus Werkzeug debugger 'để giải cứu. Khả năng chạy mã tùy chỉnh ở tất cả các cấp độ dấu vết là một kẻ giết người. Và nếu bạn hoàn toàn bị mắc kẹt, bạn có thể tạo Gist để chia sẻ chỉ bằng một cú nhấp chuột.
  2. Trang được hiển thị, nhưng kết quả là sai : một lần nữa, Werkzeug đá. Để tạo một điểm dừng trong mã, chỉ cần nhập assert Falsevào nơi bạn muốn dừng lại.
  3. Mã hoạt động sai , nhưng cái nhìn nhanh không giúp được gì. Rất có thể, một vấn đề thuật toán. Thở dài. Sau đó, tôi thường kích hoạt trình gỡ lỗi giao diện điều khiển PuDB : import pudb; pudb.set_trace(). Ưu điểm chính so với [i] pdb là PuDB (trong khi trông như bạn ở độ tuổi 80) làm cho việc thiết lập các biểu thức đồng hồ tùy chỉnh trở nên dễ dàng. Và gỡ lỗi một loạt các vòng lặp lồng nhau đơn giản hơn nhiều với GUI.

À, vâng, tai ương của các mẫu. Vấn đề phổ biến nhất (đối với tôi và các đồng nghiệp của tôi) là một bối cảnh sai: hoặc bạn không có biến hoặc biến của bạn không có thuộc tính nào đó. Nếu bạn đang sử dụng thanh công cụ gỡ lỗi , chỉ cần kiểm tra ngữ cảnh trong phần "Mẫu" hoặc, nếu không đủ, hãy đặt mã ngắt trong chế độ xem của bạn ngay sau khi bối cảnh của bạn được lấp đầy.

Vì vậy, nó đi.


gõ ít sử dụng chỉimport pudb;pu.db
Sławomir Lenart

6

Tôi đặc biệt khuyên dùng epdb (Trình gỡ lỗi Python mở rộng).

https://bitbucket.org/dugan/epdb

Một điều tôi thích về epdb để gỡ lỗi Django hoặc các máy chủ web Python khác là lệnh epdb.serve (). Cái này đặt dấu vết và phục vụ cái này trên một cổng cục bộ mà bạn có thể kết nối. Trường hợp sử dụng điển hình:

Tôi có một quan điểm rằng tôi muốn đi qua từng bước. Tôi sẽ chèn đoạn sau vào điểm tôi muốn đặt dấu vết.

import epdb; epdb.serve()

Khi mã này được thực thi, tôi mở trình thông dịch Python và kết nối với thể hiện phục vụ. Tôi có thể phân tích tất cả các giá trị và chuyển qua mã bằng các lệnh pdb tiêu chuẩn như n, s, v.v.

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

Và nhiều hơn nữa mà bạn có thể tìm hiểu về cách gõ trợ giúp epdb bất cứ lúc nào.

Nếu bạn muốn phục vụ hoặc kết nối với nhiều phiên bản epdb cùng một lúc, bạn có thể chỉ định cổng để nghe (mặc định là 8080). I E

import epdb; epdb.serve(4242)

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

lưu trữ mặc định thành 'localhost' nếu không được chỉ định. Tôi đã ném nó vào đây để chứng minh làm thế nào bạn có thể sử dụng điều này để gỡ lỗi một cái gì đó không phải là một cá thể cục bộ, như một máy chủ phát triển trên mạng LAN cục bộ của bạn. Rõ ràng, nếu bạn làm điều này hãy cẩn thận rằng dấu vết đã đặt không bao giờ xuất hiện trên máy chủ sản xuất của bạn!

Lưu ý nhanh, bạn vẫn có thể thực hiện tương tự như câu trả lời được chấp nhận với epdb ( import epdb; epdb.set_trace()) nhưng tôi muốn làm nổi bật chức năng phục vụ vì tôi thấy nó rất hữu ích.


epdb không được cập nhật kể từ năm 2011. Bạn có bao giờ gặp vấn đề khi sử dụng nó trên các phiên bản mới hơn của Django và / hoặc Python không?
Seperman

Tôi chưa bao giờ gặp vấn đề khi sử dụng nó với Python 2 (cụ thể là 2.4-2.7). Tôi đã sử dụng nó chỉ một vài ngày trước, trên thực tế. Tôi chưa bao giờ thử với Python 3.
Jacinda

1
Tôi đang chạy django 1.8 trên python 2.7 và tôi không thể tải epdb.connect để nói chuyện với epdb.serve. Tôi chỉ nhận được một thời gian chờ.
David Watson

6

Tôi vừa tìm thấy wdb ( http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401 ). Nó có giao diện người dùng / GUI khá đẹp với tất cả chuông và còi. Tác giả nói điều này về wdb -

"Có những IDE như PyCharm có trình gỡ lỗi riêng. Chúng cung cấp bộ tính năng tương tự hoặc bằng nhau ... Tuy nhiên, để sử dụng chúng, bạn phải sử dụng những IDE cụ thể đó (và một số sau đó không miễn phí hoặc có thể không có sẵn cho tất cả nền tảng). Chọn công cụ phù hợp với nhu cầu của bạn. "

Nghĩ rằng tôi sẽ vượt qua nó.

Cũng là một bài viết rất hữu ích về trình gỡ lỗi python: https://zapier.com/engineering/debugging-python-boss/

Cuối cùng , nếu bạn muốn xem một bản in đồ họa đẹp của ngăn xếp cuộc gọi của bạn trong Django, hãy kiểm tra: https://github.com/joerick/pyinstrument . Chỉ cần thêm pyinstrument.middleware.ProfilerMiddleware vào MIDDLEWARE_CLASSES, sau đó thêm? Hồ sơ vào cuối URL yêu cầu để kích hoạt trình hồ sơ.

Cũng có thể chạy pyinstrument từ dòng lệnh hoặc bằng cách nhập dưới dạng mô-đun.


PyCharm chỉ sử dụng PyDev tôi nghĩ, không phải của riêng tôi.
Rob Grant

6

Thêm import pdb; pdb.set_trace()hoặc breakpoint() (mẫu python3.7) tại dòng tương ứng trong mã Python và thực thi nó. Việc thực thi sẽ dừng lại với một vỏ tương tác. Trong shell, bạn có thể thực thi mã Python (tức là biến in) hoặc sử dụng các lệnh như:

  • c tiếp tục thực hiện
  • n bước tới dòng tiếp theo trong cùng chức năng
  • s bước tới dòng tiếp theo trong hàm này hoặc hàm được gọi
  • q thoát khỏi trình gỡ lỗi / thực thi

Xem thêm: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28


5

Một trong những lựa chọn tốt nhất của bạn để gỡ lỗi mã Django là thông qua wdb: https://github.com/Kozea/wdb

wdb hoạt động với python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) và pypy. Thậm chí tốt hơn, có thể gỡ lỗi chương trình python 2 với máy chủ wdb chạy trên python 3 và ngược lại hoặc gỡ lỗi chương trình chạy trên máy tính có máy chủ gỡ lỗi chạy trên máy tính khác bên trong trang web trên máy tính thứ ba! Thậm chí tốt hơn, giờ đây có thể tạm dừng một tiến trình / luồng python hiện đang chạy bằng cách sử dụng mã tiêm từ giao diện web. (Điều này yêu cầu gdb và ptrace được kích hoạt) Nói cách khác, đây là phiên bản pdb rất nâng cao trực tiếp trong trình duyệt của bạn với các tính năng hay.

Cài đặt và chạy máy chủ, và trong mã của bạn thêm:

import wdb
wdb.set_trace()

Theo tác giả, sự khác biệt chính đối với pdblà:

Đối với những người không biết dự án, wdb là một trình gỡ lỗi python như pdb, nhưng với phần đầu trang web mượt mà và rất nhiều tính năng bổ sung, chẳng hạn như:

  • Đánh dấu cú pháp nguồn
  • Điểm dừng hình ảnh
  • Hoàn thành mã tương tác bằng jedi
  • Điểm dừng liên tục
  • Kiểm tra các đối tượng sâu bằng cách sử dụng chuột Đa luồng / Hỗ trợ đa xử lý
  • Gỡ lỗi từ xa
  • Xem biểu thức
  • Trong phiên bản mã gỡ lỗi
  • Tích hợp máy chủ web phổ biến để phá vỡ lỗi
  • Trong trường hợp phá vỡ trong quá trình theo dõi (không phải sau khi chết) trái ngược với trình gỡ lỗi werkzeug chẳng hạn
  • Phá vỡ các chương trình hiện đang chạy thông qua việc tiêm mã (trên các hệ thống được hỗ trợ)

Nó có một giao diện người dùng dựa trên trình duyệt tuyệt vời. Một niềm vui để sử dụng! :)


Sự khác biệt với pdb là gì?
Dunatotatos

4

Tôi sử dụng PyCharm và các công cụ gỡ lỗi khác nhau. Cũng có một bài viết hay về thiết lập dễ dàng những điều đó cho người mới. Bạn có thể bắt đầu ở đây. Nó nói về PDB và GUI gỡ lỗi nói chung với các dự án Django. Hy vọng ai đó sẽ được hưởng lợi từ họ.



2

Hầu hết các lựa chọn đều được đề cập. Để in bối cảnh mẫu, tôi đã tạo một thư viện đơn giản cho việc đó. Xem https://github.com/edoburu/django-debugtools

Bạn có thể sử dụng nó để in bối cảnh mẫu mà không cần bất kỳ {% load %}cấu trúc nào :

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

Nó sử dụng định dạng pprint tùy chỉnh để hiển thị các biến trong <pre>thẻ.


2

Tôi thấy Visual Studio Code là tuyệt vời để gỡ lỗi các ứng dụng Django. Các tham số launch.json chuẩn python chạy python manage.pyvới trình gỡ lỗi được đính kèm, vì vậy bạn có thể đặt các điểm dừng và bước qua mã của mình theo ý muốn.


2

Đối với những người có thể vô tình thêm pdb vào các xác nhận trực tiếp, tôi có thể đề xuất phần mở rộng này của câu trả lời #Koobz:

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

2

Từ kinh nghiệm của riêng tôi, có hai cách:

  1. sử dụng ipdb , một trình gỡ lỗi nâng cao thích pdb.

    import ipdb;ipdb.set_trace()hoặc breakpoint() (từ python3.7)

  2. sử dụng django shell, chỉ cần sử dụng lệnh dưới đây. Điều này rất hữu ích khi bạn đang phát triển một quan điểm mới.

    python manage.py shell



1

Như đã đề cập trong các bài đăng khác ở đây - thiết lập các điểm dừng trong mã của bạn và chuyển mã để xem liệu nó có hoạt động như bạn mong đợi hay không là một cách tuyệt vời để học một cái gì đó như Django cho đến khi bạn hiểu rõ về cách tất cả hoạt động - và mã của bạn là gì đang làm

Để làm điều này, tôi khuyên bạn nên sử dụng WingIde. Cũng giống như các IDE được đề cập khác đẹp và dễ sử dụng, bố cục đẹp và cũng dễ dàng thiết lập các điểm dừng đánh giá / sửa đổi ngăn xếp, v.v ... Hoàn hảo để hình dung mã của bạn đang làm gì khi bạn bước qua nó. Tôi là một fan hâm mộ lớn của nó.

Ngoài ra tôi sử dụng PyCharm - nó có phân tích mã tĩnh tuyệt vời và đôi khi có thể giúp phát hiện ra các vấn đề trước khi bạn nhận ra chúng ở đó.

Như đã đề cập, django-debug-thanh công cụ là cần thiết - https://github.com/django-debug-toolbar/django-debug-toolbar

Và mặc dù không rõ ràng là một công cụ gỡ lỗi hoặc phân tích - một trong những mục yêu thích của tôi là SQL Printing Middleware có sẵn từ Django Snippets tại https://djangosnippets.org/snippets/290/

Điều này sẽ hiển thị các truy vấn SQL mà chế độ xem của bạn đã tạo. Điều này sẽ cho bạn ý thức tốt về những gì ORM đang làm và nếu các truy vấn của bạn hiệu quả hoặc bạn cần làm lại mã của mình (hoặc thêm bộ đệm).

Tôi thấy nó là vô giá để theo dõi hiệu suất truy vấn trong khi phát triển và gỡ lỗi ứng dụng của tôi.

Chỉ là một mẹo khác - Tôi đã sửa đổi nó một chút cho mục đích sử dụng của riêng tôi để chỉ hiển thị tóm tắt và không hiển thị câu lệnh SQL .... Vì vậy, tôi luôn sử dụng nó trong khi phát triển và thử nghiệm. Tôi cũng nói thêm rằng nếu len (Connection.queries) lớn hơn ngưỡng được xác định trước, nó sẽ hiển thị cảnh báo bổ sung.

Sau đó, nếu tôi phát hiện điều gì đó xấu (từ hiệu suất hoặc số lượng phối cảnh truy vấn) đang xảy ra, tôi bật lại màn hình hiển thị đầy đủ các câu lệnh SQL để xem chính xác điều gì đang xảy ra. Rất tiện lợi khi bạn đang làm việc trên một dự án Django lớn với nhiều nhà phát triển.


1

sử dụng pdbhoặc ipdb. Sự khác biệt giữa hai điều này là ipdb hỗ trợ tự động hoàn thành.

cho pdb

import pdb
pdb.set_trace()

cho ipdb

import ipdb
ipdb.set_trace()

Để thực hiện nphím nhấn dòng mới , để tiếp tục nhấn cphím. kiểm tra nhiều lựa chọn hơn bằng cách sử dụnghelp(pdb)


0

Một đề nghị bổ sung.

Bạn có thể tận dụng nosetestspdb cùng nhau, thay vì đưa pdb.set_trace()vào quan điểm của bạn một cách thủ công. Ưu điểm là bạn có thể quan sát các điều kiện lỗi khi chúng khởi động lần đầu tiên, có khả năng ở mã bên thứ 3.

Đây là một lỗi cho tôi ngày hôm nay.

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 %}

Bây giờ, tôi biết điều này có nghĩa là tôi đã ủng hộ nhà xây dựng cho biểu mẫu và tôi thậm chí còn có ý tưởng tốt về lĩnh vực nào là một vấn đề. Nhưng, tôi có thể sử dụng pdb để xem các hình thức giòn đang phàn nàn về điều gì trong một mẫu không?

Vâng tôi có thể. Sử dụng tùy chọn --pdb trên nosetests:

tests$ nosetests test_urls_catalog.py --pdb

Ngay khi tôi gặp bất kỳ ngoại lệ nào (bao gồm cả những trường hợp được xử lý một cách duyên dáng), pdb dừng lại ở nơi nó xảy ra và tôi có thể nhìn xung quanh.

  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)         

Bây giờ, rõ ràng rằng các đối số lựa chọn của tôi đối với hàm tạo trường giòn là vì nó là một danh sách trong danh sách, thay vì danh sách / bộ dữ liệu.

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

Điều thú vị là pdb này đang diễn ra trong mã của giòn chứ không phải của tôi và tôi không cần phải chèn thủ công.


0

Trong quá trình phát triển, thêm nhanh

assert False, value

có thể giúp chẩn đoán các vấn đề trong chế độ xem hoặc bất kỳ nơi nào khác mà không cần sử dụng trình gỡ lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.