Friday, June 26, 2009

Before I continue on with the Apache/Django series, I thought I'd post a review of the Lenovo S10e netbook. Netbooks still seem in their infancy that it's hard to pick the right one without wondering what smashing new feature is just around the corner.

Just to be clear this entire review is being typed on the netbook.

Initially upon seeing the Lenovo S10e I dismissed it. At a glance it didn't seem special, and compared to all the netbooks around it, it wasn't shiny and eye-catching. However, there were a few things that brought me back for a second look, and why I decided on this book for my Philly '09 trip:

It was the lightest (compared against an Asus Wind-120U and Acer Aspire One)

It had a 10.2" screen, again the largest of the comparasion models

It was black/dark so I didn't need to worry about the dirty-factor

In addition to that, I have discovered that...

Initially I was worried the right-shift key (which is moved to the right of the up arrow) would be problematic for typing. It's not. I haven't even noticed it.

I was also worried the keyboard would be way too small and would get in the way. Again, it doesn't. It's a comfortable size.

I've been using it now for a week, and there are definatly some factors that I do not care for...

When you close the lid the laptop just kinda, I'm not sure what it does. But when you re-open the lid hours later tapping the power button or hitting the space bar does... nothing! Maybe it's Windows or maybe I just don't use it right, but I end up having to hold the power button down, let it go completely off, and then reboot again. I wish it was more mac-like where I can just close the lid when I'm done, the netbook turns off in power-save, and then when I re-open it it powers up again.

The battery has two rear rubber feet, which when on a desk are nice, but when on your lap while sitting tend to jab into your thighs.

I miss having a "home" and "end" key, but I suppose that's the price you pay for a netbook. To be fair, there are home and end, but you have to press Fn+PgUp or Down to get them. It kinda defeats the quick home/end purpose of those keys.

Thursday, June 18, 2009

Serving up DjangoFollowing the completion of Part 2, we have an install of Django and Apache, and 2 virtual hosts running on it. What we need to do is connect those virtual hosts up to the content we need to serve.

Before we can do that, we need to add our Django app to the server. Create a folder on your webserver (anywhere really) that isn't in your document root (don't use htdocs). In my case I just made a folder off of the drive "Root_Django". Copy your django app folder into there. You should end up with something like...

C:\Root_Django\{nameofyourwebapp}

To connect Django up to Apache, we need to create a python file that will initialize WSGI and pass that information on to Django. In your {nameofwebapp} folder, create a sub folder named "apache", and then create a new file in that folder named "django.wsgi".

Be sure of course to change "{nameofwebapp}" to the actual name of your django application. This short script will take care of a few things...

the sys.path.append portion needs to point to your actual Django root. Adjust that if it's not C:\Root_Django

sys.stdout = sys.stderrd will redirect all "print" statements to the Apache error log. If you don't have any print statements in your code you can drop this, but I prefer to keep it "just in case"

This script will take care of initializing Django. All we need to do is connect up the requests to our apache virtual host to this script. Edit httpd.confi, and inside of the virtual host for your "www" host, add these lines:

This tells Apache that all requests coming in from / and up should be handled through the django.wsgi script. Save your httpd.conf file and restart Apache. You should see your Django app being served up now, minus the media (images, css, etc.).

Make sure we're also serving the grappelli media instead of the default admin media

Open up your httpd.conf file again, and find the Virtual host for your media.example.com (or whatever your static host name is). Since this will just be basic serving without WSGI, we simply need to configur the document root to the proper location...

Tada! If you were to save and restart apache, then navigation to media.example.com/some/css/file.css it should work. What we still need is to serve up the grappelli media. To do this we'll add another alias so that media.example.com/admin will serve the grappelli content.

This will make sure that all requests to /admin on your media host will serve the grappelli media files. If you installed grappelli into your Python site-packages folder, be sure to set the path to that folder instead of the django root like shown above.

Configure Django With Media PrefixesLastly for this section, we need to do some configuration in Django.

In Part 1 we installed grappelli but we haven't configured it, so we'll do that now. Also, we're using a static media virtual host, so we need to make sure that Django is prefixing our media files correctly. All of this takes place in the settings.py file.

Configure grappelliIf you'd rather see the officiall grappelli installation instructions, they are available on the grappelli google code wiki.

Wednesday, June 17, 2009

DNSI'm going to make an assumption. You have 1 domain and can create hosts under that domain. Fr example, say you own example.com. I'm assuming you have the ability to create "media.example.com" with whomever hosts your DNS.

You'll want to setup 2 domains:www.example.commedia.example.com

Since this process is virtually different for everyone I won't cover it. Contact your DNS provider for assistance here.

Setting up ApacheIf you've never used Apache, you can pretty much control the entire webserver from 1 file: httpd.conf. By default it's located in {apache install direcotory}\conf\httpd.conf. I like to edit it in Wordpad becuase I'm a lightweight, but you're welcome to edit it in whatever hacker-rific editor you prefer.

Installing mod_wsgimod_wsgi is a module addon for Apache which is responsible for accepting the incoming HTTP connection, turning that connection into a python object, and then passing it to Django. In other words, it's really important.

Copy the .so file you downloaded into {apache install directory}\modules.

Open the httpd.conf file and find the section that has all the "LoadModule"s in it

It's funny how experience changes your perspective on things. 5 years ago I tried apache and thought it was too hard. "Why can't I just have a GUI to click the settings I want?!?" I would think in frustration. Now that I'm making the transition to Django, I thought I'd give Apache another try. Wow -- What a luxury it is to be able to just write a config file to do exactly what you want to do and not have to monkey around with where some stupid settings is in an extensive maze of windows and tabs. Hah... how times change indeed.

Anyways, here's a bit about setting up Django with Apache. Here's what will be achieved:

Install all of the above, accepting the defaults (unless you otherwise know what you're doing). For mod_wsgi I'll cover installation in the next part, so hang onto it for now.

Now we'll need to do 2 SVN checkouts of code...

Installing the latest Django trunk from SVN(note: this method will have the Django development trunk as your production copy of Django. If you don't like that, then just use the installer or the tar/zip from the Django site).

In your python install directory (default: C:\Python26) open Lib and then site-packages

Create a new folder named "django"

Right-click on that folder and choose "SVN Checkout" (this will launch TortoiseSVN)

Paste this URL into that window:http://code.djangoproject.com/svn/django/trunk/django

You've now got a fresh copy of Django, but we need to configure Windows to be able to find Python and the Django tools.

Right-click "My Computer" and choose Properties (this might be slightly different for Vista+)

"Advanced" tab

"Environment Variables" at the bottom

In the "System variables" list, find "Path"

Highlight it, and hit "Edit"

Add this value to the end of it (change the path to your python path if it's not default):C:\Python26;C:\Python26\Lib\site-packages\django\bin;

Now you'll want to test to make sure this works.

Open a command prompt and type "python" and hit enter. Python should run. Ctrl+Z out of that, and type "django-admin.py help" and hit enter. It also should run.

Django and python are good to go.

Installing grappelliThis next part uses my preferences. You can do this different if you want, but keep in mind you'll need to adjust paths later on to account for your differences.

I like to install my django re-usable apps into my project directory. This adds them to the SVN trunk and I don't have to worry about if others in the office have the app installed on their local machine or not.

Anyways, open your Django project (the site you've made), and create a new folder called "grappelli". Right-click that folder and choose "SVN Checkout". Paste this URL and hit ok:

http://django-grappelli.googlecode.com/svn/trunk/grappelli

It should download a copy of grappelli. We'll look at adding it to Django in the next part.

Saturday, June 6, 2009

Well I got around to doing a 2nd revision on my model change code (being the weekend I was wondering if it would come to pass). Per a suggestion by "thepointer" (#django IRC on freenode), I switched the code from using Python's generic vars() to Django's interal _meta. Using an internal API is probably not the ultimate best, but _meta has been stable and unchanged for quite a while.

I also added a "human_friendly" mode, which will take the model change and attempt to turn it into an understandable statement (string) about what exactly has changed. It still returns it in a dictionary with the field name as the key.

fromdjango.dbimportmodels

defdetermine_model_change(old_model,new_model,human_friendly=False,ignore_fields={}):""" Compares the two models against each other, returning a dictionary of values that have changed (new value only). Setting human_friendly=True will cause ignore internal fields like SlugField. It will also attempt to parse a meaningful statement for the model change. ie 'Event date is now 5/7/2009' """not_human_fields=(models.fields.SlugField,

def__verbose_field_change(old_model,new_model,field):""" Returns the human-friendly text for a field change """value=getattr(new_model,field.name)ifisinstance(field,models.fields.DateField)or \isinstance(field,models.fields.TimeField)or \isinstance(field,models.fields.DateTimeField):

Friday, June 5, 2009

I started working more with django-notification today. However, my implementation (outside of Pynax) is to create a subscription app, particularly for subscribing to event or calendar updates. Using Django's signals, I've got most of it setup. What I needed was a way to tell the difference between the old and new event, so that the notification could actually tell you "The start time for Event X has changed to Y:ZX" instead of "An event you're watching has been updated!".

So to do that I needed some model comparision code. Here's version 1.

defdetermine_model_change(old_model,new_model):""" Compares the two models against each other, returning a dictionary of

I started using the Netbeans 6.5 Python (Early Access) IDE a couple of weeks ago, and while all seemed to be going well, one thing that bugged me was seeing all the .pyc (python compiled file) in the treeviews. Turns out NetBeans has a simple way to fix this:

On the menu go to Tools > Options

Then "Miscellaneous"

Then "Files" tab

And find the section "Files Ignored by the IDE"

This value is a regular expression which makes it easy to add the functionality we're looking for.