Friday, December 12, 2008

Django tip: AttributeError: 'str' object has no attribute 'has_header'

(permalink)
Here's another quick Django tip that I couldn't find an answer for on google:
AttributeError: 'str' object has no attribute 'has_header'


The error is the result of returning a string in a view instead of using HttpResponseRedirect. For example I accidentally wrote:
return urlresolvers.reverse('crowd-detail')


When what I meant was:
return HttpResponseRedirect(urlresolvers.reverse('crowd-detail'))


Hope that helps someone out there.

Labels:

Wednesday, October 22, 2008

Using Gmail with Django

(permalink)
It's easy to set up django to send emails through Gmail. Just use the following settings:


DEFAULT_FROM_EMAIL = 'user@gmail.com'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'user@gmail.com'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_USE_TLS = True
EMAIL_PORT = 25


Gmail supports other ports, which you can use as well. This is important if you're running thee server on your local machine, and your ISP blocks port 25.

Labels: ,

Thursday, September 18, 2008

Tried change_stage in module django.contrib.admin.views.main. Error was: 'module' object has no attribute 'change_stage'

(permalink)
Another Django upgrade hint:
Tried change_stage in module django.contrib.admin.views.main. Error was: 'module' object has no attribute 'change_stage'



Your forgot to update urls.conf as follows:

# OLD:
from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^admin/', include('django.contrib.admin.urls')),
)



# NEW:
from django.conf.urls.defaults import *
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
)

Labels:

Thursday, July 24, 2008

Django: Error while importing URLconf 'django.contrib.admin.urls': No module named urls

(permalink)
I didn't see a lot on google about this error so I thought I'd post something. If you're getting it, it's likely you updated to the latest Django SVN release, and haven't upgraded your admin site's configuration.

Read more here: http://code.djangoproject.com/wiki/NewformsAdminBranch

Labels:

Saturday, May 17, 2008

Extending the user model: profiles in Django

(permalink)
I think the documentation about using profiles & the get_profile() function isn't as clear and/or elegant as it could be. The problem with django's recommended implementation of profiles is that when a user is created, a user's profile isn't automatically created - it's not part of the same model. Managing the two can be tricky - if you mess up, you're bound to get ObjectDoesNotExist errors.

My solution was to never use get_profiles() directly - but instead add a helper method where any ObjectDoesNotExist errors are caught and resolved:


First, create a profile class in models.py:
from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    karma = models.IntegerField(default=1, core=True)
    url = models.URLField(default="", core=True)
    user = models.ForeignKey(User, unique=True)

Note, if you want to be able to create profiles using the Django admin interface, change the last line to the following:
user = models.ForeignKey(User, unique=True, edit_inline=models.TABULAR, num_in_admin=1,min_num_in_admin=1, max_num_in_admin=1,num_extra_on_change=0)


Add this line to settings.py:
AUTH_PROFILE_MODULE = 'core.UserProfile'

(change your line to 'appname.ModelName' - note, do NOT include your project name or anything else. Just your application name and model name (the model name is UserProfile, unless you change it).

Finally, add to views.py:
from django.contrib.auth.models import User
from project.core.models import UserProfile
from django.core.exceptions import ObjectDoesNotExist

def get_or_create_profile(user):
    try:
        profile = user.get_profile()
        except ObjectDoesNotExist:
        #create profile - CUSTOMIZE THIS LINE TO OYUR MODEL:
        profile = UserProfile(karma='1', url='http://example.org', user=user)
        profile.save()
    return profile


Now, in views.py, to access a user's profile, you only need two lines:
user = User.objects.get(pk = user_id)
user.userprofile = get_or_create_profile(user)


And, say if you wanted to change a value:
user.userprofile.karma += 1
user.userprofile.save()


Easy, eh?

Labels: , ,

Monday, May 12, 2008

My first attempt at a python/django application

(permalink)
You know that "a-ha" moment when yo finally get something? I think I might've just had it today. I've built my first (working) python / django application - and I think I'm actually starting to understand django & OO programming. I still have a long way to go, but it's a relief to get the hang of things.

Here it is: b l a c k l i s t e d - it's a fun little search box that will tell you if your name appears on a government watch-list. Pretty basic, but hey, what do you expect?

Labels: ,

Thursday, May 08, 2008

how to dive into web programming

(permalink)
I'm just starting to get serious about web programming, and I've done a decent amount of research about how to master it. I quickly articulated this advice in an email to a friend, and I thought I'd post it here:


Her question:
From: AM
To: Sam Odio
Subject: hi i'm curious..

Hi,

I saw that you're doing SCIP - so then I looked up what a functional programming language was, and according to wikipedia functional languages "have largely been emphasized in academia rather than in commercial software development." But it notes that you can use it for commercial use as well. So are you doing it just to learn or is to serve some future practical purpose?

I was just wondering b/c I always want to know what the best language to learn is (not that I have much of an intention of learning any sort of functional programming after getting extremely confused by your progress tracking on bluwiki) and I also know that this is all based largely on personal preference, but i'm still curious....

AM.


My response:
From: Sam Odio
To: AM
Subject: Re: hi i'm curious..

my suggestion:

1) learn an object oriented language & framework (I'm doing pything w/ djano, you can also do ruby/rails or php/symfony)
2) learn functional programming w/ SICP if you want to get good (CLisp, scheme, arc)

#2 will take a lot of time, and yield few direct results. But it'll help you understand what is capable w/ programming. Long-term results, not short-term. If you want ONLY short-term results, learn php/symfony. PHP is not completely object oriented, but quick & dirty.

-s


What does everyone think? did I give her the right advice?

Labels: , , , , , ,

Friday, April 18, 2008

Django + Python + PHP(optional) + Lighttpd on Debian etch

(permalink)
Couldn't find any great howto, so here's how I did it:

It's a good idea to update apt-get:
apt-get update


I didn't want apache running on my system:
apache2ctl stop
update-rc.d -f apache2 remove


Install lighttpd:
apt-get install lighttpd


Uncomment these lines from /etc/lighttpd/lighttpd.conf:
server.pid-file = "/var/run/lighttpd.pid"
"mod_fastcgi",
"mod_rewrite",

(you may have to add mod_fastcgi in)



If you want PHP support:
apt-get install php5-cgi


Add this line to the bottom of /etc/php5/cgi/php.ini
cgi.fix_pathinfo = 1


Add this to the bottom of vim /etc/lighttpd/lighttpd.conf:
fastcgi.server = (
".php" => ((
"bin-path" => "/usr/bin/php5-cgi",
"socket" => "/tmp/php.socket"
))
)


And add index.php if it's not already there:
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm" )





Python / Django support:

I like python 2.5.1:
apt-get install python2.5-dev
which python
cd to location of python binary
ls -lh (make sure python is a symlink)
rm python
ln -s python2.5 python


subversion to get django (also just a useful tool to have)
apt-get install subversion


Make a dir to hold all your install files:
mkdir /var/installers
cd /var/installers


Download & install:
wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py


Get flup for python support:
wget http://www.saddi.com/software/flup/dist/flup-0.5-py2.5.egg
easy_install flup-0.5-py2.5.egg


Django:
svn co http://code.djangoproject.com/svn/django/trunk/ ./django-trunk/
cd ./django-trunk
python setup.py install


Edit /etc/lighttpd/lighttpd.conf and change fastcgi.server to:
fastcgi.server = (
".php" => ((
"bin-path" => "/usr/bin/php5-cgi",
"socket" => "/tmp/php.socket"
)),
"django.fcgi" => (
"main" => (
"host" => "127.0.0.1",
"port" => 9090, #set the port numbers to what-eva you want
),
),
"admin.fcgi" => (
"admin" => (
"host" => "127.0.0.1",
"port" => 9091,
)
)
)

(notice php support - that's optional)


Add rewrite rules to lighttpd.conf:
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^(/static.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/admin/.*)$" => "/admin.fcgi$1",
"^(/.*)$" => "/django.fcgi$1"
)


Now make blank dummy files to prevent Lighttpd 404 errors:
vim /var/www/django.fcgi
vim /var/www/admin.fcgi


Now make a django project directory (www):
mkdir /var/django
cd /var/django


make a test project:
django-admin.py startproject testproject


Add the following line to the settings.py file of the django project on the server:
FORCE_SCRIPT_NAME = ''

(this prevents redirects to django.fcgi)

start the project:

cd ./testproject
python manage.py runfcgi method=prefork host=127.0.0.1 port=9090 pidfile=django.pid

Note - using port 127.0.0.1 for runfcgi doesn't limit lighttpd to only that interface. It's used for communication between lighttpd & runfcgi

now test!
http://your_server_ip


Mysql support (haven't tested to see if this works):
I run my database on a separate server, if you don't, you'll need to set up mysql server as well. There are plenty of HOWTOS on that, try googling around.

apt-get install mysql-client

(will add config instructions later, once I do them)

Install MySQLdb, which lets python easily talk to mysql (haven't yet tested/configured this):
apt-get install python-mysqldb

Labels: , , , ,