Django — Override ModelAdmin ChangeList Ordering By Annotate and Aggregate

I ran into trouble overriding django’s ModelAdmin ChangeList Ordering.

Overriding the ModelAdmin.queryset did not help because while the Queryset can be defined, the ordering is overridden by `ChangeList.get_ordering`

My solution is to override the ModelAdmin get_changelist method and return a subclassed ChangeList.

class AccountAdmin(admin.ModelAdmin):   
    # ...
    
    def get_changelist(self, request, **kwargs):
        """
        Returns the ChangeList class for use on the changelist page.
        
        Force get_ordering to return None (if no ordering specified)
        to prevent  from applying ordering.
        """
        from django.contrib.admin.views.main import ChangeList
        
        class SortedChangeList(ChangeList):
            def get_query_set(self, *args, **kwargs):
                qs = super(SortedChangeList, self).get_query_set(*args, **kwargs)
                return qs.annotate(amt=Sum('entry__amount')).order_by('-amt')
                
        if request.GET.get('o'):
            return ChangeList
            
        return SortedChangeList

We take advantage of the fact that get_changelist can be overridden, and the fact that get_query_set is called AFTER ordering is done on the ChangeList.

Let me know if you have other solutions!

Python — Globally Override Function Imports

To globally override imports (per python session), modify sys.modules to whatever you’d like.

import sys

sys.modules['csv'] = 'I just replaced the csv module'

import csv
print csv  # output 'I just replaced the csv module'

That’s pretty straight forward, but if you need to replace a function within a module, you’d have to pull out the module, set the new function, and set the module in sys.modules.


import sys

module = sys.modules['module']
module.myfunction = lambda: 'my new function'

sys.modules['module'] = module

from module import myfunction
myfunction() # output 'my new function'

Python — Script to Rename Files and Crop Images in Directory

I’m often using python to rename files for me or process them in batches when I need to save some time / immense boredom, and I do it so infrequently I generally have to look at reference material.

Here some code for future reference.

"""
Python Rename Script
=========

This is just some one off code I wrote to save myself from doing repetative tasks. 

It probably took as long as manually renaming them and cropping the files.

The source files were in this format:
- name fun.jpg
- name work.jpg

I needed them in the following format:
- team_name.jpg
- team_name2.jpg 

and at specific dimensions.

I at first just wanted to rename, but found out some images were odd sizes.
"""

import re
import os
import shutil
from PIL import Image, ImageOps

dirname = os.path.abspath('.')
file_paths = os.listdir(dirname)

for _file in file_paths:
    try:
        matches = re.findall('(.*) (fun|work)\.jpg', _file)[0] # find name & if fun or work.
        name = matches[0]
        _type = matches[1]
        prefix = 'team_'
        suffix = ''
        if _type == 'fun':
            suffix = '2'
        
        new_name = prefix + name  + suffix + '.jpg'
        
        image = Image.open(_file)
        
        imagefit = ImageOps.fit(image, (150, 170), Image.ANTIALIAS, 0, (0.5, 0))
        imagefit.save('tmp/'+ new_name, 'JPEG', quality=90)
        
    except Exception, e:
        print e, _file
        
        # I don't really care about when this fails..
        # it would fail on any regex match failure like .DS_STORE (OSX file)
        # or my tmp directory

Mac OSX – Python Imaging Library PIL on Mac 10.6

Installing PIL was no problem, but I couldn’t import it.

I used homebrew, PIP, easy_install, they all say it’s correctly installed in the various directories.

I just decided to fix it by going to /Library/Python/2.6/site-packages and making a symlink from the egg file to to PIL

cd /Library/Python/2.6/site-packages
ln -s PIL-1.1.7-py2.6-macosx-10.6-universal.egg/ PIL

I suggest you not dwell on it and do this instead.

TextMate — CSS File Type for .css.liquid extensions

The default Liquid bundle will conflict with CSS Liquid files meaning syntax highlighting will off for CSS Liquid.

I had to switch between CSS and HTML Liquid since both files have .liquid endings.

To add css.liquid to the CSS language, push cmd+option+control+L, click on CSS, click on CSS again, and add ‘css.liquid’ to the ‘fileTypes’ line.

Django — Automatically importing modules for python manage.py shell

Ever wonder how many hours of time you’ve wasted importing the same things over and over at the start of a python manage.py shell?

Imagine the number of times you forgot to import datetime or decimal, or your model even.

I’ve finally had enough and looked up ways around this problem.

Luckily, this iPython solution is amazingly easy. Cut and paste code into iPython’s config files (which are python as well) and you’re done!

http://djangosnippets.org/snippets/549/

It will take 2 minutes max.

Django / Postfix — Connection Refused on send_mail on OSX

I was having trouble sending email from my local development environment (OS X) via django’s send_mail, and thus smtplib.

I figured out I need to enable postfix for OSX following the directions here:
http://www.agileapproach.com/blog-entry/how-enable-local-smtp-postfix-os-x-leopard-0

Except I had to do as a comment mentioned in the post, write each key/value as its own line, like so:

	<key>RunAtLoad</key> 
	<true/> 
	<key>KeepAlive</key> 
	<true/>

Check if postfix is running by typing sudo postfix status

If it’s not running, just start it: sudo postfix start

Now try connecting to it via localhost port 25

s = smtplib.SMTP('localhost')
# or send_mail
django.core.mail.send_mail(...)

Django — How to Order Inline ForeignKey

To apply ordering to a foreign key in the admin, you simply define an “ordering” attribute in your ModelAdmin.

But what about Inlines?

To apply ordering to an Inline Model’s foreign key, override the default form of the admin.StackedInline or admin.TabularInline subclass by specifying a ModelForm.

class OrderedInlineForm(forms.ModelForm):
    product = forms.ModelChoiceField(queryset=Product.objects.order_by('name'))
    class Meta:
        model = MyInlineModel

class MyInlineModelAdmin(admin.StackedInline):
    model = MyInlineModel
    form = OrderedInlineForm