Django widget renderer render

July 9th, 2010

I got a little frustrated trying to find the ‘simple’ answer to change the html which is generated by the various form field widgets.

In this case the RadioSelect field generates radio buttons wrapped in an unordered list. It was annoying, and whilst I could resort to writing the html directly in the html; that’s not ideal.

The solution is not hard, just not well documented.

We need only write a “render” routine to return the string we want. Then override the default widget with our renderer, and finally specify all that in the form field definition:

from django import forms
from django.forms import ModelForm
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode

FULFILMENT_CHOICES = (
    ('Post','Post'),
    ('Pickup','Pickup')
)

class MyRadioRenderer(forms.widgets.RadioFieldRenderer):    """Render radio buttons without the <li>"""
    def render(self):
        return mark_safe(u'\n%s\n' % u'\n'.join([u'%s'
                    % force_unicode(w) for w in self]))

class OrderForm(ModelForm):
   fulfilment = forms.ChoiceField(
              widget=forms.RadioSelect(renderer=MyRadioRenderer),
              choices=FULFILMENT_CHOICES)

Produces:

<div class="orderValue">
<label for="id_fulfilment_0"><input type="radio" id="id_fulfilment_0" value="Post" name="fulfilment"/> Post</label>
<label for="id_fulfilment_1"><input type="radio" id="id_fulfilment_1" value="Pickup" name="fulfilment"/> Pickup</label>
</div>

How to complete the BAS Online

May 12th, 2010

The Australian Tax Office (ATO) have a very tiresome mandatory requirement for all business’s to submit a form every 3 months. The effect of the “Business Activity Statement” (BAS) is to tell the ATO how much they should bill you for; and they will chase you hard for the money that you’ve just told them that you owed them, so be prepared to pay it.
Read more…

How to configure an open samba share

February 10th, 2010

I’m always battling to expose my linux virtual machines to my windows desktop. Here is a sample smb.conf which completely exposes a directory to a specific IP address:


security = share
hosts deny = ALL
hosts allow = 192.168.1.99

[www]
path = /var/www
available = yes
browsable = yes
public = yes
writable = yes
force user = www-data
guest account = www-data
guest ok = yes

[Django] How to replace an image using ModelForm

December 14th, 2009

I have a user profile model which holds their ‘mugshot’ image. I’m using modelForm to to present a profile update form. It was easy to build a working form, but now I need a couple of tweaks to the image:

1) it saves with the filename that the user provides; I rather dictate the filename to use. I thought I’d just use the PK of the model, and the same file extension eg: “443.jpg”

2) it should replace the existing image, not append an underscore like “443___.jpg”.

Here’s my model and form:

class Member(models.Model):
    home_phone      = models.CharField(max_length=10, blank=True)
    image           = models.ImageField(upload_to='members', default="default.png")
    ...

class MemberProfileForm(forms.ModelForm):
   home_phone      = AUPhoneNumberField(required=False)

   class Meta:
       model = Member
       exclude = ('email','password','create_date','last_login','is_active')

This seems to solve it by altering the filename and deleting the existing file prior to the form save.

form = MemberProfileForm(request.POST, request.FILES, instance=request.member)
if form.is_valid():
    if form.cleaned_data['image']:
        (path, extension) = os.path.splitext(form.cleaned_data['image'].name)
        form.cleaned_data['image'].name = ('%s%s' % (request.member.id, extension))
        request.member.image.delete()
    form.save()

… excepting that most people probably want ‘request.user’, where I have ‘request.member’.

Date formats and Django forms

December 13th, 2009

Date formats are something that US dominance remains unable to overcome. Whilst all software assumes a format of mm/dd/yyyy, all other nations of the world want to change that to their local preference.

Django is no exception.

Here’s the magic incantation to make Django 1.1 output and input dates in an Australian format.


DATE_FORMAT = '%d/%m/%Y'
...
class ProfileForm(forms.ModelForm):
    ...
    date_of_birth = forms.DateField()
    date_of_birth.widget = forms.DateInput(format=DATE_FORMAT)
    date_of_birth.input_formats = (DATE_FORMAT,)

domainnamegroup.com.au is a scam

December 10th, 2009

I got this letter in the mail recently. At first glance I thought, “oh, does my programmerforhire.com.au domain need renewal already?”…

I have a sneaking suspicion that’s exactly the reaction this item was intended to provoke…
don’t get stung by domain name scams

My errors always return to jQuery’s “success” function?

December 4th, 2009

How do I tell my application that the query was unsuccessful when jQuery insists on always running the “success” function when it returns??

When we make an ajax call with jQuery the server’s response is consumed by the “success” function we’ve provided. “success”, in this case, refers to whether the server responded according to the HTTP protocol. “success”, in this case, does not refer to whether the application was happy to do what we were asking for, or not. If the user tried to do something silly don’t expect that putting a function in the “error” callback will deal with it. “error” and “timeout” are only useful if you want to know when the ajax request couldn’t converse with the server at all.

Q: So how do I tell my application if the call was successful or not?

A: Return a JSON response.

For example have your server return:

{'success': false; "message": "Nah. I'm not in the mood", 'id': 292} or
{'success': true; "message": "Okey dokey!", 'id': 292}

If, in your ajax call, you set the “dataType” to “json” jQuery automatically parses the json and gives you a javascript object all ready to go. Man, this was so wonderful, I thought I should blog it.

This little sample throws up a dialog to present ‘data.message’, then uses ‘data.success’ to decide if the action was successful or not. If it was successful we could use data.id for something useful. But in this case I fade out an element identified with the id passed to the original manage function which is somehow still in scope.


function manage(action, id){
    $.ajax({
        type: "POST",
        data: "action=" + action + "&id=" + id,
        url: "/membership/xhr/manage/",
        dataType: "json",
        success: function(data){
            $("<div></div>").html(data.message).dialog();
                modal:true,
                buttons: {
                    "Ok": function(){
                        $(this).dialog("close");
                        if(data.success) $('#membership_'+ id).fadeOut();
                    }
                }
            });
        }
    });
}

I’d give you a working demo, but that would be work ;-)

Age in years with python?

November 30th, 2009

Given someone’s date of birth how do I work out their age? This is actually less trivial than first appears because:

  • the person’s age doesn’t increment until their birthday passes on the calendar
  • that day is not always the same period of time after midnight on the 1st of January

This solution works by asking if today’s month is before their birthday, and if their birthday is this month whether today’s date is before the birth day.

This works even if they are born on the 29th of Feb.


def age(dob):
    import datetime
    today = datetime.date.today()

    if today.month < dob.month or \
       (today.month == dob.month and today.day < dob.day):
          return today.year - dob.year - 1
    else:
          return today.year - dob.year

>>> import datetime
>>> datetime.date.today()
datetime.date(2009, 12, 1)
>>> age(datetime.date(2008, 11, 30))
1
>>> age(datetime.date(2008, 12, 1))
1
>>> age(datetime.date(2008, 12, 2))
0

How to convert a VMWare vmdk appliance to VirtualBox vdi

March 22nd, 2009

There are loads of ready-built appliances for VMWare in .vmdk format but I use VirtualBox and there is never a release in .vdi form to be found. I’ve heard that virtualbox will run the vmware images… but is that true?

Yes you can run vmware drives in virtualbox. Here’s how…

How to push wordpress from testing to production

March 8th, 2009

I use a testing server for my site, and I use wordpress. I create and update content on testing, then deploy it to production. But the wordpress import procedure won’t update an existing post so…

How do I deploy my wordpress content from Testing to Production?