Jquery and Effect.ScrollTo
It was beginning to become a bane: missing scriptaculou's Effect.ScrollTo. And then I found this gem.
Improved Animated Scroll Script For Same-Page Links
And all is well again.
Blog of Titus Stone; Part programmer, part... wait... what?
It was beginning to become a bane: missing scriptaculou's Effect.ScrollTo. And then I found this gem.
Improved Animated Scroll Script For Same-Page Links
And all is well again.
Posted by titus at 10:18 AM 0 comments
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:
Posted by titus at 12:55 PM 0 comments
Part 1 | Part 2 | Part 3
Serving up Django
Following 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".
Paste this script into that file:
import os, sysBe sure of course to change "{nameofwebapp}" to the actual name of your django application. This short script will take care of a few things...
sys.path.append('C:\\Root_Django')
sys.path.append('C:\\Root_Django\\{nameofwebapp}')
os.environ['DJANGO_SETTINGS_MODULE'] = '{nameofwebapp}.settings'
# Remap stdout to err
sys.stdout = sys.stderr
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
WSGIScriptAlias / C:\Root_Django\{nameofwebapp}\apache\django.wsgi
<Directory "C:\Root_Django\{nameofwebapp}">
Order deny,allow
Allow from all
</Directory>
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.).DocumentRoot "C:\Root_Django\{nameofwebapp}\media"
<Directory "C:\Root_Django\{nameofwebapp}\media">
Order deny,allow
Allow from all
</Directory>
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.Alias /admin "C:\Root_Django\{nameofwebapp}\grappelli\media"
<Directory "C:\Root_Django\{nameofwebapp}\grappelli\media">
Order deny,allow
Allow from all
</Directory>
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.Next, add the grappelli template directory:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.request",
"grappelli.context_processors.admin_url",
)
Lastly, of course, add grappelli to your list of installed apps:
import os
here = lambda x: os.path.join(os.path.abspath(os.path.dirname(__file__)), x)
TEMPLATE_DIRS = (
# ...
here('grappelli/templates/'),
)
Configure Media Prefixes
INSTALLED_APPS = (
# ...
'grappelli',
)
But this could easily become problematic when we're testing django with runserver. A better result would be to conditionally test if we're in DEBUG mode, and to change the value based on that.
MEDIA_URL = 'http://media.example.com/'
if DEBUG:We'll also want to make sure the admin media files from grappelli are being served. The code is almost identical, expect the setting is ADMIN_MEDIA_PREFIX:
MEDIA_URL = '/media/'
else:
MEDIA_URL = 'http://media.example.com/'
if DEBUG:At this point Django should be running, and serving media files.
ADMIN_MEDIA_PREFIX = '/grappelli/media/'
else:
ADMIN_MEDIA_PREFIX = 'http://media.example.com/admin/'
Posted by titus at 7:54 AM 0 comments
Part 1 | Part 2 | Part 3
DNS
I'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.com
media.example.com
Since this process is virtually different for everyone I won't cover it. Contact your DNS provider for assistance here.
Setting up Apache
If 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_wsgi
mod_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.
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com:80
ServerAdmin you@example.com
</virtualhost>
<VirtualHost *:80>
ServerName media.example.com:80
ServerAdmin you@example.com
</VirtualHost>
Posted by titus at 4:05 PM 0 comments
Part 1 | Part 2 | Part 3
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:
http://code.djangoproject.com/svn/django/trunk/djangoPosted by titus at 3:45 PM 0 comments
My desktop for June
OS: Windows XP
Wallpaper: Watercolor Emico
Dock: RKLauncher
Dock Skin: AluCurved3D
Desktop Info: Samurize
Posted by titus at 6:48 AM 0 comments
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.
from django.db import models
def determine_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,
models.fields.FilePathField,
models.IPAddressField,
models.FileField,
models.ImageField,
models.XMLField,
)
changed = {}
if isinstance(old_model, models.Model) and isinstance(new_model, models.Model):
for f in new_model._meta.fields:
if not f.name in ignore_fields:
new_value = getattr(new_model, f.name, '')
old_value = getattr(old_model, f.name, '')
if cmp(new_value, old_value) != 0:
if human_friendly:
if not type(f) in not_human_fields:
changed[f.name] = __verbose_field_change(old_model, new_model, f)
else:
changed[f.name] = new_value
return changed
def __verbose_field_change(old_model, new_model, field):
"""
Returns the human-friendly text for a field change
"""
value = getattr(new_model, field.name)
if isinstance(field, models.fields.DateField) or \
isinstance(field, models.fields.TimeField) or \
isinstance(field, models.fields.DateTimeField):
value = value.strftime('%b %d, %Y %I:%M %p')
return '%s %s has changed to %s' % (
old_model,
field.verbose_name,
value
)
# -------------
# Sample usage:
# -------------
>>>
>>> from happenings.models import *
>>> import copy, datetime
>>>
>>> event = Event.objects.get(pk=1)
>>> event.name = "My Birthday"
>>> event.start_time = datetime.datetime(2009, 7, 5, 0, 0)
>>>
>>> newevent = copy.copy(event)
>>> newevent.start_time = datetime.datetime(2009, 7, 15, 0, 0)
>>>
>>> determine_model_change(event, newevent)
{'start_time': datetime.datetime(2009, 7, 15, 0, 0)}
>>>
>>> determine_model_change(event, newevent, human_friendly=True)
{'start_time': 'My Birthday start time has changed to Jul 15, 2009 12:00 AM'}
Posted by titus at 10:11 AM 0 comments
Labels: django, django-models, python
© Blogger template 'Minimalist G' by Ourblogtemplates.com 2008
Back to TOP