NinjaCipher:-*-:ro60

Archive for December, 2007

Django Render To Response Hack

Saturday, December 29th, 2007

I was working on perva.de and I needed to add a cookie to the response. Now thats not really a tough thing to do but it has one unfortunate side effect. Basically it makes you have to use the long handed method for rendering the template instead of being able to use the more concise render_to_response shortcut. Reason being that the render_to_response shortcut creates a HttpResponse object for you and when you create a cookie you already have a HttpResponse object thats holding your cookie. So I wrote this simple function that lets you pass in your own pre initialized HttpResponse object instead.

def render_response(*args, **kwargs):
        response = kwargs.pop('response', None)
        if response == None:
            from django.shortcuts import render_to_response
            return render_to_response(*args, **kwargs)
        else:
            from django.template import loader
            response.content = loader.render_to_string(*args, **kwargs)
            return response

You call it the same way as the normal render_to_response except it has an optional param that lets you pass in your pre initialized HttpResponse object.

return render_response('index.html',{'param1': 'param1value'},context_instance=RequestContext(request),response=my_response)

If you pass None as the first param the normal render_to_response is called. The context_instance and the params dict are both optional. You can read about how the normal render_to_response works here.

Now for the disclaimer…

I could be completely missing something simple that already allows you to do this but I didn’t see it. It seems like a very common prob and the folks at the Django project are sick python masters so it wouldn’t surprise me if they already though this through. So if that is the case please leave me a comment and/or call me names and enlighten me to the folly of my ways. I won’t hate you… much ;)

EDIT: I refactored the way the request arg was passed to make it more python like and cleaner. Now you pass it as a kwargs key val pair.

Django Pagination Wrapper

Thursday, December 27th, 2007

For my current project perva.de, I’ve been playing with Django’s core pagination class django.core.paginator.ObjectPaginator. I wrote this wrapper that adds some nice functions that are helpful for rendering. Drop me some comments if you have ideas on how it could be better or “hey ro60 your an idiot you should do this instead” is always welcome too. ;)

Please to enjoy… yes?!

"""
    This object inherits from the Django core ObjectPaginator class and
    provides some aditional helpful calculations for rendering pagination links
"""
from django.core.paginator import ObjectPaginator, InvalidPage
class NFPaginator(ObjectPaginator):

    def _set_current_page(self, current_page):
        try:
            self._current_page = int(current_page)
        except:
            self._current_page = 0

    def _get_current_page(self):
        return self._current_page

    def _get_display_page(self):
        if self._current_page == 0:
            return 1
        else:
            return self._current_page

    def _get_next_page(self):
        try:
            if ObjectPaginator.has_next_page(self,self._current_page):
                return self._current_page + 1
            else:
                return -1
        except:
            NFLogger.message(sys.exc_info(),"exception")

    def _get_previous_page(self):
        try:
            if ObjectPaginator.has_previous_page(self,self._current_page):
                return self._current_page - 1
            else:
                return -1
        except:
            NFLogger.message(sys.exc_info(),"exception")

    def get_page(self, page_number):
        #if the page is invalid then we get the first page
        try:
            return ObjectPaginator.get_page(self,page_number)
        except InvalidPage:
            self._current_page = 0
            return ObjectPaginator.get_page(self,self._current_pager)

    def render_next(self):
        return ObjectPaginator.has_next_page(self,self._current_page)

    def render_previous(self):
        return ObjectPaginator.has_previous_page(self,self._current_page)

    display_page = property(_get_display_page)
    current_page = property(_get_current_page,_set_current_page)
    next_page = property(_get_next_page)
    previous_page = property(_get_previous_page)

Then in your view

from pervade.netflippers import NFPaginator
def index(request):
    if 'page' in request.GET:
        page = request.GET['page']
    else:
        page = 0

    paginator = NFPaginator(Bookmark.objects.all().order_by(’-created_at’), 2,0)

    paginator.current_page = page
    latest_bookmark_list = paginator.get_page(page)
    return render_to_response(’bookmarks/index.html’, {’latest_bookmark_list’: latest_bookmark_list, ‘paginator’:paginator}, context_instance=RequestContext(request))

This all makes rendering a template allot simpler. Here is a link to a template partial that you can use.

P.S. There are calls to my logger class in here as well. Feel free to rip them out if you wish OR better yet include the logger as well.


Thx to Timmah for the comments. I’ve edited the get_page method to fix the blind page display issue.

Handy Django Logger

Sunday, December 23rd, 2007

Here is a handy little logger I wrote for Django. Feel free to use it if you want and to give me your thoughts on improvements. It was my first stab so be gentle. ;)

Big thx to… http://www.linuxjournal.com/article/5821 for exception formatting code…

netflippers.py

from django.conf import settings
import logging
import sys
import traceback

class NFLogger():

    """
        The only requirement for this logger is that you have LOG_FILE
        set in your settings.py
    """
    def __init__(self):
        logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=settings.LOG_FILE)

    """
        Static method that will call any of our members based on a string name
        for example: NFLogger.message(sys.exc_info(),"exception")
    """
    @staticmethod
    def message(message,methodname='debug'):
        logger = NFLogger()
        if hasattr(logger, methodname):
            _member = getattr(logger, methodname)
            _member(message)
        else:
            logger.debug(message)

    def info(self,message):
        logging.info(message)

    def error(self,message):
        logging.error(message)

    def warn(self,message):
        logging.warn(message)

    def critical(self,message):
        logging.critical(message)

    def debug(self,message):
        logging.debug(message)

    """
        This will output formatted info about the current exception.
        Just pass sys.exc_info() from inside your except block
    """
    def exception(self,sys_exc_info):
         cla, exc, trbk = sys_exc_info
         excName = cla.__name__
         try:
             excArgs = exc.__dict__["args"]
         except KeyError:
             excArgs = “”
         excTb = traceback.format_tb(trbk)
         logging.error(”nException Name: %snException Arguments: %snException Traceback: %sn”,excName, excArgs, excTb)

Just stick this in your Django app and set the path to your desired log file in your settings.py and you should be good to go.

In settings.py

LOG_FILE = '/tmp/pervade.log'

In your code

from pervade.netflippers import NFLogger
NFLogger.message("hi there")

or

NFLogger.message("hi there","info")

Or in an except block:


import sys

try:
    somecode.thaterrorsout
except:
    NFLogger.message(sys.exc_info(),"exception")

Slicehost VPS VS Media Temple GS

Friday, December 21st, 2007

Ok I know the VS posts are an invitation to start flame wars and I really don’t like the idea of that but to be honest I think allot of good insight can be gained by a good flamewar so why the hell not. That being said I recently signed up for both a Slicehost VPS and a Media Temple GS account and I’d like to share my thoughts on both. They both start at 20$ a month and both allow you to scale nicely (albeit in slightly different ways) so I think it’s an obvious comparison, and honestly I would have loved to read about this when I was initially looking. PS I’m purposely going to steer clear of the grid vs vps scaling methodologies. You can read plenty about the merits of each approach on the respective sites.

Media Temple GS:
I started out first with the Media Temp account. I must admit the idea behind the Grid Server is very enticing. And to be honest Media Temple is very good at marketing. They have allot of buzz(not all good) and I figured hell why not. I had read all the initial reports about the issues with the grid hosting but I wasn’t really bothered by it. Besides it was quite a few months since they launched the product line and to be honest anyone who buys into something that is brand new and expects it to be bug free is smoking grade A jub rocks. For instance look at any Apple product… their great but only after they have been out for awhile and all the bullshit has been worked out.

So I decided to give them a shot. Hell its only 20$ a month. Not much to loose really. The setup was simple. They have a stupid easy admin interface. I also like the 1 click installers. This blog is running off of a one click install of Wordpress. The account also comes with email support. Cool… if there is one this I HATE its trying to setup and deal with my own email servers. It’s a serious pain and I was glad that they had that covered for me. So far so good…

Now on to the stuff I’m not thrilled about…

First… the server is fairly slow. I’ve talked to them a few times about this and they have even comp’d me a free month. It’s bearable and for a 20$ a month shared host it’s not surprising but with all the hype I would think that it would be faster.

Second… they give you very little access. I’m really used to having root. Call me crazy but I like to be in control. At work I have my own rack in colo so not having root is a kick in the nutz. I basically have to play nice with their control panel to do the majority of my configuration. Now I can do that and most likely thats fine for allot of the people who subscribe to this service but its kinda a buzzkill. Any of you sudo junkies out there know what I mean….

Third… every site is lumped under the parent site. Now don’t get me wronge I’m happy that you can host a bunch of vhosts under one account but I don’t really like that fact that in the control panel everything is nested under the main site. It makes me feel bad for my other sites. Like they are the red headed step children or something. I don’t know. I’m picky I guess. If you have a gs account you know what I mean. If you don’t well trust me is annoying.

Fourth… I CANT RUN DJANGO(yet). Ok I know this is changing but it’s taking FAR too long… that sux. Nuff said.

Slice Host VPS:
First off I love that they offer Ubuntu. I use that on all my work servers and I think it’s an awesome flavor. I also love that they give you a bucket full of tasty root access. WOOT I GOT ROOT! The server is fast too. Like really fast. That shit they say about not overselling their machines… well they must not be bullshitting because I have the dinky 256 slice and it’s blazing. So with root comes the power to install whatever. This pleases me to no end. I can finally run django.

Potential Drawbacks: (for some people)

First… no real control panel. Well they have something that lets you control your vps but as for setting up sites and databases etc your out of luck. I don’t use GUI control panels anyway so this is fine with me but I can see it would be a turn off to some people.

Second… no pre-configured email setup. Now no one is saying you can’t setup your own but there is nothing there out of the box.

Third… no one click install apps. I only mention this as it’s something I liked about my media temple account.

To sum it all up…
I think both product lines have their merits. For a beginner/hobbyist or someone who would rather concentrate of making your site then setting up your server I think Media Temple GS is an excellent choice. For someone who is already versed in server administration and doesn’t mind getting down and dirt with some server config I think slicehost is an excellent option.

As for me I’ll prob keep both. I like having my blogs on a server that I don’t really have to think about but the lack of speed and access kills me when it comes to development. So for my projects slicehost will get my money.

Just my 2 cents… Flame on flamers ;)