Django South Notes

South

South is “a tool to provide consistent, easy-to-use and database-agnostic migrations for Django applications.” However, as South’s website says, since Django 1.7 now has its own migrations tool South has been deprecated. I personally think the new Django migrations are a little bit better.

However we still use South at FiveStars and I thought other people who still use South might appreciate these notes.

See list of migrations (asterisks means already applied)

[shell]
$ ./manage.py migrate –list [app name]
[/shell]

Apply latest migrations

[shell]
$ ./manage.py migrate [app name]
[/shell]

Fake migration

[shell]
$ ./manage.py migrate [app name] [version #] –fake
[/shell]

Migrate backwards

[shell]
$ ./manage.py migrate [app name] [version #]
[/shell]

Migrate back to zero state, i.e. nothing

[shell]
$ ./manage.py migrate [app name] zero
[/shell]

Create first migration

[shell]
$ ./manage.py schemamigration [app name] –initial
[/shell]

Create subsequent migrations

[shell]
$ ./manage.py schemamigration [app name] —-auto
[/shell]

Create empty schema migration

[shell]
$ ./manage.py schemamigration [app name] —-empty [migration name]
[/shell]

Create data migration

[shell]
$ ./manage.py datamigration [app name] [migration name]
[/shell]

Review migration history

[sql]
select * from south_migrationhistory order by applied;
[/sql]

Redo migrations that have been hand edited

Sometimes you will find someone followed the bad practice of hand editing a migration after it has been committed. For example they’ll add another column. Because you have already run the migration you may not notice this until many migrations later when something breaks because of this missing column.

To fix this:

  1. Fake migration backwards to the edited migration
  2. Migrate back one before the edited migration
  3. Migrate forward one for the edited migration
  4. Fake migrate forwards the rest until you get to your current state
  5. Migrate the migration that previously was giving problems

JavaScript Invalid Argument in Internet Explorer Only

Today I noticed one of my links were not working.  This was only happening in Internet Explorer 8.  Looking down at the status bar in the lower left corner I saw the message “Error on page.”  Double-clicking on it popped up this window full of useless information.

Internet Explorer 8 invalid argument JavaScript error

A Google search for “internet explorer invalid argument” brought me to this page, Internet Explorer Sucks.  Fortunately the author had run into this problem and figured out the solution.

It turns out In Internet Explorer, the second argument to the JavaScript window.open method, which is the windowName argument, can’t have spaces. My original link looked like this.

<a href="javascript:void(0);" onclick="window.open('popUp.jsp','Frank Kim betweenGo','menubar=0,toolbar=0,location=0,scrollbars=yes,width=400,height=175')">What's this?</a>

When I took out the spaces from the windowName argument the link worked.  You would think Internet Explorer 8 would have fixed this issue by now, it doesn’t affect any other modern web browser.

YouTube Embedded Player Parameters

Here is a page describing the YouTube Embedded Player Parameters.  These parameters are query parameters you can add to the end of the YouTube URL.

There are different parameters you can add to the object and embed statements.  Here is an example.

<object width="320" height="265">
 <param name="movie" value="http://www.youtube.com/v/6sHenGpeGgo&hl=en&fs=1&autoplay=1"></param>
 <param name="allowFullScreen" value="true"></param>
 <param name="allowscriptaccess" value="always"></param
 <param name="wmode" value="transparent"></param>
 <embed src="http://www.youtube.com/v/6sHenGpeGgo&hl=en&fs=1&autoplay=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="320" height="265"></embed>
</object>

HTTP Proxy

Recently I was having a problem where a Flash video was not being displayed.  It turned out the Flash video had not been created properly and had a dependency on other Flash files that were not available.  When I was viewing this Flash video directly using JBoss I did not see any errors.  But when I viewed it using Apache the logs showed the dependency problems.

Another developer, Allan Scott, suggested next time I use Charles or Fiddler as HTTP proxies.

Did you try watching the HTTP traffic with a tool like Fiddler or Charles?

If there is a dependency on something and it failed to download it then you should be able to see the 404 or some other error.

Unobtrusive JavaScript

Unobtrusive JavaScript’s goal is to move all the functionality (the Controller) out of the HTML (the Model) and the CSS (the View).  This is also called full MVC separation.

This is how typically JavaScript and HTML mix.  For example in submitting a form using a text link.

<a href="javascript:submit(document.testForm)">Submit</a>

Or for jumping to different parts of a page using a dropdown.

 <input type="image" src="/img/buttons/update.gif"
   onClick="window.location.hash=
document.jumpTo.names.options[document.jumpTo.names.selectedIndex].value">

Using the unobtrusive JavaScript technique one can separate the JavaScript from the HTML.

<div id="foo">Submit</div>

<script type="text/javascript">
 Event.observe($('foo'), 'click', function(event) {
   $(Event.element(event)).form.submit();
   return false;
 });
</script>

We use the Protoculous JavaScript file which combines the Prototype framework and Scriptaculous libraries to do unobtrusive JavaScript.

Undefined

Nouveau Variation on Flickr

(Photo: Nouveau Variation by Syntopia)

I find the undefined keyword and identity operators (=== and !==) in JavaScript pretty useful.  For example if I am parsing a JSON input and I am not sure if something is there or not I test it like this.

if (root.Foo === undefined)

If I want to test if something is defined I do it like this.

if (root.Bar !== undefined)

saladwithsteve explains it well in his JavaScript undefined vs. null post.

Update 12-14-2009: Unfortunately the above method did not work for testing a variable directly.  I ended up following the advice of this post, Javascript IsDefined Function.  To test if a variable is defined I now do this.

if (typeof(foo) != "undefined")

WordPress Impressive Permalink Functionality

A long time ago I enabled the WordPress permalink functionality so that the links for my blog articles were somewhat human readable.  I used my own custom format, /%category%/%year%/%monthnum%/%day%/%postname%/.

Awhile ago I began regretting that format because if I changed the category of the article then the URL would change and any bookmarks to that article would be broken.

Today I started reorganizing a lot of categories and decided it was time to bite the bullter.  I changed the permalink format to the standard /%year%/%monthnum%/%day%/%postname%/.   What was so impressive is that the old URL’s still worked, they redirected to the new URL.  WordPress rocks.

smush.it

Image optimization is an art that not many people master. There are many good image editing tools that allow us to get the best visual result for a certain file size but “under the hood” a lot more optimization can be done.

Smushit.com is a service that goes beyond the limitations of Photoshop, Fireworks & Co. It uses image format specific non-lossy image optimization tools to squeeze the last bytes out of your images – without changing their look or visual quality. You’ll get a report of how many bytes you can save by optimizing your images and all the changed images as a single zip for download.

Smush it comes in different flavours:

  • You can upload a bunch of pictures in your browser
  • You can provide us with a list of image urls or
  • You can get a Firefox Extension to optimize the images found on any web page

Saving bytes has never been so easy – you point us in the right direction, and we’ll do the rest for you. A ZIP archive with optimized images will be generated for you.

New from the Yahoo Performance team.

Takes your image(s) and makes their file size as small as possible: converts GIF to PNG8, throws out JPG metadata, etc.  Does not make JPGs more lossy; the results look exactly the same.

Install the Firefox plugin and you can hand it a URL — and when it’s done, it’ll give you a ZIP file of all the images from that URL in reduced form.

Our Travel page, for instance:
Smushed 12.97% or 30.14 KB from the size of your image(s).
I’m actually pretty pleased we are “only” 30KB over.  I’d have thought it’d be more.

Our visitor HIW page:
Smushed 30.48% or 51.16 KB from the size of your image(s).

Browser Security Warnings

This is from my friend, Chris Weekly.

I think it is necessary for us to be precise when we talk about “security popups” as there are many different kinds.

Some of these are always preventable, some are unavoidable in certain scenarios, all vary according to the browser version and its user config.

Anyway here’s a kickstart:

  1. SSL Certificate Warnings (various) – Triggered on HTTPS URL’s on domains with an expired or self-signed certificate. 
  2. Insecure Content Warnings – Triggered on HTTPS URL’s when the page contents embed references to HTTP resources (images, iFrames, stylesheets or scripts).
    This is preventable by proper JSP/taglib usage. Note it is ok for links to use http:// even in https:// pages as they’re not automatically followed.
  3. HTTPS to HTTP Redirection Warnings – Triggered when an HTTPS request triggers a redirect to an HTTP URL.
    This is unavoidable in some scenarios but should be avoided by design whenever possible.
  4. HTTP/HTTPS Switch Alert – Triggered when simply navigating from HTTP to HTTPS or back.
    This is out of our control, but most browsers don’t have this on by default, and users tend to turn this global setting off after seeing it once or twice (on any site) as it’s so common and harmless.
  5. Content not under this site’s control (New) – Apparently resulting from the recent Microsoft security patch.
    I believe this is triggered by scripts which are not on the same domain as the page requested.
    This is most likely to arise w/ 3rd-party tracking pixel-related scripts.  Needs more investigation.

    Update: I may have made an incorrect assumption that it related to recent MS security updates; it might instead be triggered by attempts of javascript on one domain to interact w/ the page on another domain. Which script and whether this is in fact the root cause of #5 is TBD. 

There are others but I think these are the main ones we’ve been dealing with lately.

Thanks,
Chris