Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I troubleshoot in Django?

Tags:

python

django

I come from a PHP background and I've been trying to learn Python but I'm having a lot of trouble when it comes to debugging as I'm not yet sure how to go about this in Django or Python in general.

I'm used to being able to print_r or var_dump everything in PHP. I could do it in the controller, In a service layer or the even the model and data would show up in my web browser.

I can't do this in Django. Depending on what I'm doing, attempting to just perform a print on an object from my view will bring the page down or output something to my console that doesn't really help me. Here's an example:

class Page(View):
    def get(self, request, *args, **kwargs):
       response = Data.objects.all()

       # for whatever reason, I want to print something right now:
       print response

       # return JsonResponse({'success':response})

The above will take down my page completely with a notice saying:

The view didn't return an HttpResponse object. It returned None instead.

There are some instances while working with CBV's where I noticed I could get the data to just dump somewhere such as the console. But it wouldn't be anything that would help me. For instance if I was trying to to take a look at the contents of response from above, it would just show up like so:

[object Object] [object Object] [object Object]

A var_dump would have allowed me to actually see inside of it.

So I'm guessing I'm going about this all wrong. Do people just dump data when they're debugging in Python? If they do, how do you perform this, and does it show up in the web browser or the console? If not, how do I go handle basic troubleshooting in Django? Example scenarios:

  1. I want to see the contents of a list or dictionary
  2. I want to see the raw sql query being performed by the ORM
  3. I want to see if a function is being executed by slipping some text inside to be outputted on the front end
like image 396
user2989731 Avatar asked Oct 20 '14 02:10

user2989731


People also ask

How do you check that Django is working?

Simply type python -m django --version or type pip freeze to see all the versions of installed modules including Django.

What to do if Django admin is not working?

To fix this, first close the terminal window and relaunch it with administrator privileges. Once you launch the elevated terminal window change directory to where you wish to start your Django project. The command should work.

What is Django error?

Server errorsWhen DEBUG is False , Django will email the users listed in the ADMINS setting whenever your code raises an unhandled exception and results in an internal server error (strictly speaking, for any response with an HTTP status code of 500 or greater).


3 Answers

The basic problem is that you are used to how PHP is wired into the entire request/response chain, and this is not how Python is configured when developing web applications.

In PHP-world, the server guarantees a response, which closes the request/response cycle. The PHP file is directly requested by the browser, so you are unaware of what is actually happening in the background.

A typical PHP request, is just the same as a request for any other static asset, like a plain index.html file or logo.gif. The browser requests, the web server accepts the request, and then returns the response; the only difference being if a file with .php is requested, then it goes through an intermediary step where the PHP interpreter evaluates the file, and sends the result back to the client.

In Python however, when a request is made that is mapped to a Python backend process (sometimes called upstream process); the webserver waits for a response from the process (the timeout for this can be adjusted). If a response isn't received within the defined timeout, the webserver sends a timeout error page (504 ERROR).

It is the responsibility of the Python process to send a proper response (with all headers, etc.) as is expected by the browser. In PHP, this is hidden from you (as the developer), because the PHP engine will add these extra information for you. So when you have Python code that does not send such a response (as in your case), django helps you out by printing a friendly error message.

In your case - the view is not returning a response; its just printing something. This print statement will go to the standard output (or error stream) of the application (will be printed on the console if you launched it on the shell, or written to the server's log, etc.) it will not be sent back to the client (the browser).

In order to debug django applications:

  1. Make sure DEBUG = True is set in your settings.py
  2. Run your application with python manage.py runserver

Now, when you do any print statement, it will be shown on the console and if there is an error in your application code - as long as you are returning a valid response - you will get a rich error page along with a stack trace to help identify the problem.

There is no more "debugging statements and printing things on the browser" as you are developing; this is just how Python is wired into the web world.

For your other questions:

  1. I want to see the contents of a list or dictionary

    Simply print it. The output will be on your console (the same place where you wrote python manage.py runserver)

  2. I want to see the raw sql query being performed by the ORM

    If you are testing things out in the django shell, you can just put .query at the end of your ORM call to see the query being sent:

     >>> result = MyModel.objects.filter(foo='bar')
     >>> result.query
     (query printed here)
    

    For a more rich debugging experience, install django_debug_toolbar.

  3. I want to see if a function is being executed by slipping some text inside to be outputted on the front end

    There is no "outputting to the front end". For such things, you can just print() what you need, or even better use the logging system.

like image 137
Burhan Khalid Avatar answered Sep 29 '22 05:09

Burhan Khalid


First, the reason you're getting an error isn't because you're printing, it's because you commented out the return:

class Page(View):
    def get(self, request, *args, **kwargs):
       response = Data.objects.all()

       # for whatever reason, I want to print something right now:
       print response

       return JsonResponse({'success':response}) # <-- dont comment this out

Secondly, printing arbitrary objects won't always provide the best amount of information. If something defines a __str__ or __unicode__ method, that's what will be printed to the console. Otherwise, the object name along with its memory id will be printed. Not the most useful. Printing an object doesn't do a "deep" print.

You can try to print out the locals and globals:

print(locals())
print(globals())

Or serialise an object to JSON and print that:

print(json.dumps(response)) # some objects may not be serialisable to JSON though.

But you may not get the amount of detail you want from that either. The alternative is to run your webserver in debug mode, and raise an exception:

# settings.py
DEBUG = True

# views.py
def my_view(request):
    raise Exception('debug')

.. and rely on django to show you the debug error page, which includes a stack trace, and allows you to inspect all the variables available in each frame.

like image 21
Josh Smeaton Avatar answered Sep 29 '22 07:09

Josh Smeaton


First off, Django views require some sort of HttpResponse object to be returned. From the docs- In contrast to HttpRequest objects, which are created automatically by Django, HttpResponse objects are your responsibility. Each view you write is responsible for instantiating, populating and returning an HttpResponse.

There are many classes that that you can use to return that response (render_to_response, HttpResponseRedirect, JsonResponse and many, many more- https://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses). Your line # return JsonResponse({'success':response}) will do that if you get rid of the #.

Instead of a var_dump, you can use Python's dir function. All attributes of a class or class instance will be shown. See- Is there a function in Python to print all the current properties and values of an object?

  1. You can print a dictionary. There are many ways to do it.

    for key,value in your_dictionary.items(): print(key, ":", value)

  2. Easy to do. print Data.objects.all().query . See - How to show the SQL Django is running

  3. Or you could add print statements inside the function (or a decorator that states the function is executing).

These are pretty basic parts of Django and Python. Not to be rude, but your time would probably be better spent doing some tutorials in full than embarking on your own projects. Once it clicks, it will be very simple. MVC/MVT frameworks have a different structure than PHP and you'll need to get used to working within it or will be frustrated.

like image 27
Ian Price Avatar answered Sep 29 '22 07:09

Ian Price