Django has some very useful error pages built in that can help with a lot of debugging. Unfortunately sometimes you need to dig into the code a little more at run time to track down errors, etc.

Here are some additional methods for debugging Django…

Using pdb

pdb is part of the Python standard library. It allows you to set breakpoints, inspect objects, etc.

In Django, start your local server by invoking pdb

python -m pdb manage.py runserver

In your code, add this line right before the line you want to set a breakpoint on

import pdb; pdb.set_trace()

At the breakpoint, you will see the command line terminal stop and a (Pdb) prompt will show up. From here you can enter an object’s name to inspect it. You can also run simple functions to see what they output.

For example:

(Pdb) request.is_ajax()
True

Just type c to continue on from a breakpoint.

This article is a work in progress…

The Amazon Web Services (AWS) website has instructions for doing this, but they are mostly tailored to doing it on a Linux machine. Here’s how to do it on Windows 7.

Prerequisites

  • Download and unzip the Elastic Beanstalk command line tools package (eb)
  • TIP: Unzip it into a directory so that there are no spaces in the full filepath. Spaces + command line = not fun.

    Add eb to the path

    set PATH=%PATH%;C:\Users\andygilbertson\AWS-ElasticBeanstalk-CLI-2.6.0\eb\windows\
  • Python 2.7
  • Make sure Git is installed
  • Have virtualenv installed
  • To install with PIP, here’s the command:

    pip install http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.7.2.tar.gz

    Steps

    Open up a command prompt (cmd.exe, not PowerShell)

    Create a virtual environment

    cd C:\
    virtualenv --python=C:\Python27\python.exe Users\andygilbertson\envs\django_aws_hello
    NOTE: The second argument is optional. It is the version of Python you want the virtual environment to build.
    NOTE: The slashes are reversed from what the Amazon documentation has. The command won’t accept the second argument unless you reverse the directory slashes correctly.

    This will create a mini Python installation in the directory. You can go there and see the files to confirm.

    Go into the newly created “Scripts” directory

    cd C:\Users\andygilbertson\envs\django_aws_hello\Scripts

    Then activate the virtual environment

    activate
    NOTE: This is where you don’t want to be using PowerShell. VirtualEnv’s activate script is subject to execution policies on Windows. For some reason cmd.exe doesn’t have issues.

    Now you’ll see your virtual environment name in parentheses to indicate you are in your virtual environment
    Inside your virtual env, install django and python

    pip install django==1.6.2
    easy_install MySQL-python==1.2.5
    NOTE: Getting mysql-python to install correctly was way harder than it should have been. I think the problem is that on Windows this package has some Visual Basic dependencies (C compiler), as noted by the developer. Installing it via easy_install rather than pip solved the issue.

    Start the Django project locally

    cd..
    django-admin.py startproject hellodjango

    Go into the newly created root folder for your local Django site

    cd hellodjango

    Create the requirements.txt file

    pip freeze > requirements.txt

    After freezing, requirements.txt should look like this:

    Django==1.6.2
    mysql-python==1.2.5

    Initialize the Git repository

    git init .

    Make sure you’re in the project directory

    cd C:\Users\andygilbertson\envs\django_aws_hello\hellodjango

    Run eb init

    eb init

    Now you’ll have to fill in a bunch of Elastic Beanstalk settings.

    Here’s the link if you need fresh access keys

    Settings to choose

    • Environment Tier: WebServer::Standard::1.0
    • Solution stack: 32bit Amazon Linux 2013.09 running Python 2.7
    • Environment type: LoadBalanced
    • Create an RDS DB instance: y

     

    On your local computer, create an .ebextensions directory in the top-level directory of your source bundle. In this example, we use /root/mysite/.ebextensions.

    mkdir .ebextensions

    Create a configuration file (myapp.config)

    container_commands:
      01_syncdb:    
        command: "django-admin.py syncdb --noinput"
        leader_only: true
    
    option_settings:
      - namespace: aws:elasticbeanstalk:container:python
        option_name: WSGIPath
        value: mysite/wsgi.py
      - option_name: DJANGO_SETTINGS_MODULE
        value: mysite.settings
      - option_name: AWS_SECRET_KEY
        value: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
      - option_name: AWS_ACCESS_KEY_ID
        value: AKIAIOSFODNN7EXAMPLE
    
    NOTES:
    • Make sure you fill in all four of the option_settings with your data.
    • Make sure your config file doesn’t have tab characters. Use only spaces for indenting

    Save this .config file in the newly created .ebextensions directory

    Edit your settings.py file (/root/mysite/settings.py). Add this for the DATABASES object:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': os.environ['RDS_DB_NAME'],
            'USER': os.environ['RDS_USERNAME'],
            'PASSWORD': os.environ['RDS_PASSWORD'],
            'HOST': os.environ['RDS_HOSTNAME'],
            'PORT': os.environ['RDS_PORT'],
        }
    }

    Add these files to the Git repository and commit the changes

    git add .
    git commit -m "eb configuration"
    git aws.push

    New you can run eb start to actually initialize Elastic Beanstalk with all the settings

    eb start

    When it’s all up and running (it takes about 15 minutes) you should be able to get some status info

    eb status --verbose

    When the server status is Green, you should be able to grab the supplied URL and plug it into your browser. If everything went according to plan, you’ll see Django’s basic welcome page.

    If you see the Elastic Beanstalk starter page (not Django’s), you may have to run Git aws.push again.

    git aws.push

    Troubleshooting

    One of the first places to look is the AWS Console. Go to Elastic Beanstalk, find your environment. On the left you’ll see “Logs”. “Snapshot Logs” and read through them to find errors.

    Closing Up Shop

    To stop the Elastic Beanstalk server/environment

    eb stop

    To delete the Elastic Beanstalk server/environment

    eb delete

    To deactivate your virtual environment

    cd C:\Users\andygilbertson\envs\django_aws_hello\Scripts
    deactivate

This doc is a work in progress…

Using Django version: 1.6.2

Basic Ajax Example

views.py

from django.shortcuts import render
def basicajax(request):
    context = {}

    # Draw initial page
    if request.method == 'GET':
        return render(request, 'basic_ajax.html', context)

    # Handle posts
    elif request.method == 'POST':

        # Make sure request is Ajax
        if request.is_ajax():
            context['textbox_data'] = request.POST['textbox']
            context['hiddenfield_data'] = request.POST['hiddenfield']

            # Return response as JSON
            return HttpResponse(json.dumps(context), content_type='application/json')
    else:
        # Handle errors here
        pass
Notes

  • We are returning an HttpResponse, not a render
  • content_type='application/json' is necessary. Otherwise the Ajax success callback returns the data as a string
  • content_type used to be mimetype. Some documentation online still shows up using this but it is now deprecated. Use content_type
  • The data that is passed in from the hidden fields can be used to separate different Ajax requests from the same page. Just give each Ajax form an identifier in a hidden field and use that field to handle the logic in views.py

basic_ajax.html

<html>
<head>
    <title>Basic Ajax Example</title>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
</head>
<body>
    <form id="form_id1">
        <input type="text" name="textbox">
        <input type="submit" value="Search">
        <input type="hidden" name="hiddenfield" value="Cant see me">
        {% csrf_token %}
    </form>
    Textbox value: <span id="textbox_val"></span>, Hidden field value: <span id="hiddenfield_val"></span>
</body>
<script>
$(document).ready(function() {
    $("#form_id1").submit(function(event){
        // Disable submit button
        $("#form_id1").find('input[type=submit]').prop("disabled",true);

        $.ajax({
            type:"POST",
            url:"",
            data: $("#form_id1").serializeArray(), // Easy way to capture all data from form
            success: function(data) {

                // Fill in our output spans
                $("span#textbox_val").html(data['textbox_data']);
                $("span#hiddenfield_val").html(data['hiddenfield_data']);

                // Enable submit button
                $("#form_id1").find('input[type=submit]').prop("disabled",false);
            },
            error: function(xhr, textStatus, errorThrown) {
                alert("Please report this error: "+errorThrown+xhr.status+xhr.responseText);
            }
        });
        return false; //<---- so page doesn't reload
    });
});</script>
</html>
Notes

  • Imports jQuery at the top
  • url="", within the Ajax call to submit to same page
  • To fill the data in the Ajax call use serializeArray(), not serialize()
  • {% csrf_token %} must be present within each form

urls.py

from django.conf.urls import patterns, include, url
from hellodjango.views import *
urlpatterns = patterns('',
    url(r'^examples/basicajax/', basicajax),
)