RSS Icon

Topics

View Comments

Exception occurred processing WSGI script with Django

Topics: django python

If you are running Django under mod_wsgi on apache you might see errors like "IOError: failed to write data" followed by "Exception occurred processing WSGI script" in your logs, this is because your code is actually throwing an exception but Django likes to hide any errors from your users (for obvious reasons).

Usually Django would send you an e-mail with the full callstack of the error to ADMINS defined in your settings.py but if you don't have your e-mail settings or ADMINS properties configured it will not be able to send you your e-mail report.

Also, if you have your e-mail host server defined wrong (i.e gmail.com instead of smtp.gmail.com) your server will just keep churning and never load your 404 or 500 server errors.

If you don't have an SMTP server to use and need to see the exception your site is throwing you could always set Debug=True but then anyone who accesses your site in that time will also see the information of the exception.

To use g-mail with django click here

For Django documentation on email settings click here

View Comments

Tips and Tricks for the Python Interpreter

Topics: django python

I have seen a lot of people switch over to using ipython, bpython, etc to get auto-complete support without realizing that the standard interpreter does have this functionality.

To enable auto-complete support in the python interpreter you need to create a python startup file that enables readline support. A python startup file is just a bunch of python code that gets executed at startup of the interpreter. To do this you just setup PYTHONSTARTUP in your ~/.bashrc and then create a ~/.pythonrc.py file:

#.bashrc
PYTHONSTARTUP=~/.pythonrc.py
export PYTHONSTARTUP

#.pythonrc.py
try:
    import readline
except ImportError:
    print("Module readline not available.")
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")

Now when you are in python you have tab completion on importing, calling methods on a module, etc.

>>> import o
object(  oct(     open(    or       ord(     os 

I always end up using the pretty print module for viewing long lists and strings in the interpreter so I prefer to just use it by default:

# Enable Pretty Printing for stdout
import pprint
def my_displayhook(value):
    if value is not None:
        try:
            import __builtin__
            __builtin__._ = value
        except ImportError:
            __builtins__._ = value

        pprint.pprint(value)

sys.displayhook = my_displayhook

It is also very useful to be able to load up your favorite editor to edit lines of code from the interpreter, you can do this by adding the following into your ~/.pythonrc.py:

import os
import sys
from code import InteractiveConsole
from tempfile import mkstemp

EDITOR = os.environ.get('EDITOR', 'vi')
EDIT_CMD = '\e'

class EditableBufferInteractiveConsole(InteractiveConsole):
    def __init__(self, *args, **kwargs):
        self.last_buffer = [] # This holds the last executed statement
        InteractiveConsole.__init__(self, *args, **kwargs)

    def runsource(self, source, *args):
        self.last_buffer = [ source.encode('latin-1') ]
        return InteractiveConsole.runsource(self, source, *args)

    def raw_input(self, *args):
        line = InteractiveConsole.raw_input(self, *args)
        if line == EDIT_CMD:
            fd, tmpfl = mkstemp('.py')
            os.write(fd, b'\n'.join(self.last_buffer))
            os.close(fd)
            os.system('%s %s' % (EDITOR, tmpfl))
            line = open(tmpfl).read()
            os.unlink(tmpfl)
            tmpfl = ''
            lines = line.split( '\n' )
            for i in range(len(lines) - 1): self.push( lines[i] )
            line = lines[-1]
        return line

c = EditableBufferInteractiveConsole(locals=locals())
c.interact(banner='')

# Exit the Python shell on exiting the InteractiveConsole
sys.exit()

For Django developers when you load up the ./manage.py shell it is nice to have access to all your models and settings for testing:

# If we're working with a Django project, set up the environment
if 'DJANGO_SETTINGS_MODULE' in os.environ:
    from django.db.models.loading import get_models
    from django.test.client import Client
    from django.test.utils import setup_test_environment, teardown_test_environment
    from django.conf import settings as S

    class DjangoModels(object):
        """Loop through all the models in INSTALLED_APPS and import them."""
        def __init__(self):
            for m in get_models():
                setattr(self, m.__name__, m)

    A = DjangoModels()
    C = Client()

After these tweaks the python interpreter is a lot more powerful and you really lose the need for the more interactive shells like ipython and bpython. All of these settings work in both python2 and python3.

If you want to see my complete ~/.pythonrc.py you can get it on github

View Comments

Using gmail to send e-mails from Django

Topics: django python

To send an e-mail through django's SMTP server you just have to define a few variables in your settings.py

EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'user@gmail.com'
EMAIL_HOST_PASSWORD = 'pw'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

You can test to make sure your settings work properly by loading up the python interpreter:

$> ./manage.py shell
from django.core.mail import EmailMessage
email = EmailMessage('Subject', 'Body', to=['user@gmail.com'])
email.send()

If you define a wrong EMAIL_HOST like 'gmail.com' instead of 'smtp.gmail.com' email.send() will just sit there and churn and not give you a response back.

View Comments

Caesar Cipher in Python

Topics: interview python

I'm currently teaching my wife to code and one of the problems that we worked on to teach her some fundamental programming concepts was re-implementing the caesar cipher in python. It was fun not only to code but to also start sending each other "secret" messages!

The caesar cipher is a rather simple encoding, you just shift the alphabet a certain amount of characters. For example, if you are using a shift of 2:

a => c
b => d
y => a
z => b

Using this as an interview type question would provide a few interesting problems and give you a good perspective on how good a developers problem solving skills are and how knowledgeable they are in the language of their choice.

The first issue is to handle the beginning and end of the alphabet, if you are encoding 'z' then you will have to start your shift on a. The second problem is to only encode letters since there was no ascii table to define in what order characters are shifted back in those times.

Without using too much of the built in python niceties you could do something similar to this:

#!/usr/bin/python
def decode_shift_letter(current_ord, start, end, shift):
    if current_ord - shift < start:
        new_ord = (current_ord + 26) - shift
        return chr(new_ord)
    else:
        return chr(current_ord-shift)
    
def encode_shift_letter(current_ord, start, end, shift):
    if current_ord + shift > end:
        new_ord = (current_ord - 26) + shift
        return chr(new_ord)
    else:
        return chr(current_ord+shift)

def decode(input, shift):
    return modify_input(input, shift, decode_shift_letter)

def encode(input, shift):
    return modify_input(input, shift, encode_shift_letter)

def modify_input(input, shift, shift_letter):
    new_sentence = ''

    for letter in input:
        # we only encode letters, random characters like +!%$ are not encoded.
        # Lower and Capital letters are not stored near each other on the 
        # ascii table
        lower_start = ord('a')
        lower_end = ord('z')
        upper_start = ord('A')
        upper_end = ord('Z')
        current_ord = ord(letter)

        if current_ord >= lower_start and current_ord <= lower_end:
            new_sentence += shift_letter(current_ord, lower_start, lower_end, shift)
        elif current_ord >= upper_start and current_ord <= upper_end:
            new_sentence += shift_letter(current_ord, upper_start, upper_end, shift)
        else:
            new_sentence += letter

    return new_sentence


def get_shift():
    try:
        shift = int(raw_input('What shift would you like to use?\n'))
    except ValueError:
        print 'Shift must be a number'
        shift = get_shift()

    if not (shift > 0 and shift <= 25):
        print 'Shift must be between 1 and 25'
        shift = get_shift()

    return shift

def main():
    try:
        task = int(raw_input('1) Encode \n'+ \
                             '2) Decode \n'))
    except ValueError:
        print 'Invalid task, try again!'
        main()

    shift = get_shift()
    input = raw_input('What message would you like to %s\n' % ('Encode' if task == 1 else 'Decode'))

    if task == 1:
        print encode(input, shift)
    elif task == 2:
        print decode(input, shift)

if __name__ == '__main__':
    main()

This would prove that you are a decent problem solver and have enough of the language to get things done but if you want to prove you have mastered the python language you might take advantage of some slicing and some methods out of the string module and change your code to look something like:

from string import letters, maketrans

def decode(input, shift):
    return modify_input(input, -shift)

def encode(input, shift):
    return modify_input(input, shift)

def modify_input(input, shift):
    trans = maketrans(letters, letters[shift:] + letters[:shift])
    return input.translate(trans)

Do get more information on string.letters and string.maketrans you can visit their documentation here

View Comments

Extending the Django User Model

Topics: django python

Django provides a very powerful user system out of the box but since it has to be generic enough to ship with the framework they don't provide a lot of extra fields to store additional information about your users, that is left up to you as the developer.

Django doesn't leave you hanging though, they provide all the tools you need to easily and quickly extend the included model.

The first thing you need to do is define a model with a foreign key to the base user model with all the additional information you would like to store:

from django.db import models

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    company = models.CharField(max_length=255, blank=True, null=True)
    nickname = models.CharField(max_length=255, blank=True, null=True)

After that you need to tell Django about your profile model in settings.py:

AUTH_PROFILE_MODULE='app.UserProfile'

Now you can call get_profile() on any user instance and it will return the matching UserProfile instance but you need to make sure you actually create the profile when you create the user.

The first way to do this is to attach post_save and post_delete signals:

from django.db import models

def user_post_delete(sender, instance, **kwargs):
    try:
        UserProfile.objects.get(user=instance).delete()
    except:
        pass

def user_post_save(sender, instance, **kwargs):
    try:
        profile, new = UserProfile.objects.get_or_create(user=instance)
    except:
        pass

models.signals.post_delete.connect(user_post_delete, sender=User)
models.signals.post_save.connect(user_post_save, sender=User)

Check out the Django documentation for signals here

The one big flaw with that approach is that you don't actually have access to any of the UserProfile additional information so you need to provide default values or allow all fields to be null. If you want the ability to require certain fields in a profile you'll need to handle the creation in your form itself.

To override the built in UserCreationForm and adding your profile fields you just inherit from it and then override the save method:

from django.contrib.auth.forms import UserCreationForm

class UserForm(UserCreationForm):
    nickname = forms.CharField(required=True)
    company = forms.CharField(required=True)

    def save(self, commit=False):
        user = super(UserForm, self).save(commit=False) 
        user.save()

        try:
            profile = user.get_profile()
        except:
            profile = UserProfile(user=user)

        profile.nickname = self.cleaned_data['nickname'']
        profile.company = self.cleaned_data['company']
        profile.save()

        return user

Another quick little trick is to use python's property() method to define a profile property directly on your model. This will solve the issue of having to create your profile when you create the user but still has the issue that your additional fields can't be required:

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

Now that you have created the property on the model you no longer need to call get_profile(), you can access the profile directly:

from django.contrib.auth.models import User
user = User.objects.get(pk=1)
user.profile.nickname = 'nickname'

The biggest flaw with this implementation is that it makes a database query every time you access the profile property, so you will want to implement some sort of caching.

For more information on storing additional information about users in Django you can check out the documentation here.

Older Newer