July 2012

archive

change an existing model, auth_user.username, max_length in django Jul
06
1
2

So lets say I had a model an an app that I didn't create that I wanted to change. Well, I would like to avoid going to that app and adjusting the code on the fly. Instead I would rather make the change in my custom application in order to keep the integrity of the code strong.

In my personal case I typically need to increase the max_length of the username in the django.contrib.auth package. You can perform the change by using the class_prepared signal:

# models.py
from django.db.models.signals import class_prepared

def longer_username(sender, *args, **kwargs):
    # you can't just do `if sender == django.contrib.auth.models.User`
    # because you have to import the model
    if sender.__name__ == 'User' and sender.__model__ == 'django.contrib.auth.models.User':
        sender._meta.get_field('username').max_length = 100

class_prepared.connect(longer_username)

You might need to change any help_text and forms.

This code will not update the underlying database. In order to make the update in the database I add a South schema migration.

import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):
    def fowards(self, orm):
        db.alter_column('auth_user', 'username', models.CharField(max_length=100))

    def backwards(self, orm):
        db.alter_column('auth_user', 'username', models.CharField(max_length=35))

# copy the rest of the file from the previous migration
# update the value for auth.user / username / maxlength

I don't think I need to say this, but this is hackish and should be used with great caution.

comments

html5 django form fields Jul
06
1
2

If you're ever developing for mobile it's really handy to use the HTML5 form inputs for things like email and url to bring up the contextual keyboard layouts.

An easy way to create the HTML5 input elements is to extend the Input widget input_type.

from django import forms
from django.widgets import Input


class Html5EmailInput(Input):
    input_type = 'email'


class Html5URLInput(Input):
    input_type = 'url'


class CustomForm(forms.Form):
    email = forms.CharField(widget=Html5EmailInput())
    url = forms.CharField(widget=Html5URLInput())

comments

removing a passphrase from an SSL Key Jul
06
1
2

This is taken from http://www.mnxsolutions.com/apache/removing-a-passphrase-from-an-ssl-key.html

The typical process for creating an SSL certificate is as follows:

# openssl genrsa -des3 -out www.key 2048

Note: When creating the key, you can avoid entering the initial passphrase altogether using:

# openssl genrsa -out www.key 2048

At this point it is asking for a PASS PHRASE (which I will describe how to remove):

 Enter pass phrase for www.key:

 # openssl req -new -key www.key -out www.csr

Next, you will typically send the www.csr file to your registrar. In turn, your registrar will provide you with the .crt (certificate) file.

From a security standpoint utilizing a passphrase, is a good thing, but from a practical standpoint not very useful.

For instance, what happens when your server reboots/crashes at 3am? Or better, what happens in 6 months when you reboot your machine, and you don’t remember the password? Well, one thing is for sure, your web server will not be online.

I suggest removal of the passphrase, you can follow the process below:

Always backup the original key first (just in case)!

# cp www.key www.key.orig

Then unencrypt the key with openssl. You’ll need the passphrase for the decryption process:

# openssl rsa -in www.key -out new.key

Now copy the new.key to the www.key file and you’re done. Next time you restart the web server, it should not prompt you for the passphrase.

comments

bind a model's .change() trigger to a view's .render() function in backbone Jul
06
1
2

You can bind a Model's .change() trigger to a View's .render() function in Backbone by using the bindAll method to make sure the render method is always bound to the view.

MyView = Backbone.View.extend({
    initialize: function() {
        _.bindAll(this, "render");
        this.model.bind('change', this.render);
    },

    render: function() {
        this.model.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

comments

adding paths to the lessc compiler Jul
06
1
2

So you need to compile your less files but you've put the files somewhere else in your directory structure and need to add paths for lessc to search.

There is an undocumented option include-path that does just this. The source code looks like:

        case 'include-path':
            options.paths = match[2].split(os.type().match(/Windows/) ? ';' : ':')
                .map(function(p) {
                    if (p) {
                      return path.resolve(process.cwd(), p);
                    }
                });
            break;

which if you read it carefully tells you it can accept one or more directories separated by ":" or ';' if you're on windows. So, to include new paths for lessc to search you can pass in the directories like so:

lessc --include-path="/path/to/directory/" styles.less
lessc --include-path="/path/to/directory/:/path/to/another/directory/" main.less > styles.css

comments

display the value of a django form field in a template Jul
06
1
2

Sometimes you need to get at the raw value of a field in a django form. This is easily done in 1.3 using the following:

{{ form.field_name.value }}

If you're running a version lower than 1.3 you can get at the value with:

{% if form.instance.field_name %}
{{ form.instance.field_name }}
{% else %}
{{ form.data.field_name }}
{% endif %}

comments

accessing the object inside a django admin change_form.html template Jul
06
1
2

When overriding the change_form.html template sometimes I need access to the object that is being edited. The change_view method provides the original object in the 'original' context variable.

You can access the object in the template using the original variable:

{{ original }}

comments