Tuesday, 21 July 2009

Improved Django FormWizard

A few months back I had a project that I thought needed a wizard-style interface for one of its forms. For a while now Django has included the FormWizard class in django.contrib.formtools.wizard so I decided to use that. However, I immediately hit a couple of issues with it.

FormWizard requires you to output the previous_fields context variable in each of the form's step templates. Django's FormWizard previous_fields is just a string of raw HTML. If you are using some other kind of markup to do your forms e.g. XForms, or even javascript widgets from dojo or extjs, then this is no good.

I quickly came up with a fix for this and opened #10557 which has now been slated to be included in Django 1.2.....

Wait a minute! Django 1.1 isn't even out yet!

The second issue was that FormWizard didn't handle FormSets.

Who knows when 1.2 will be out so I've bundled up my code and released it as wadofstuff.django.forms 1.0.0.

From the README:

Functions

security_hash(request, form, exclude=None, *args)

Calculates a security hash for the given Form/FormSet instance.

This creates a list of the form field names/values in a deterministic
order, pickles the result with the SECRET_KEY setting, then takes an md5
hash of that.

Allows a list of form fields to be excluded from the hash calculation. This
is useful form fields that may have their values set programmatically.

Classes

BoundFormWizard

A subclass of Django's FormWizard that adds the following functionality:
  • Renders previous_fields as a list of bound form fields in the template context rather than as raw html.
  • Can handle FormSets.
The usage of this class is identical to that documented here with the exception that when rendering previous_fields you should change your wizard step templates from:

{{ previous_fields|safe }}

to:

{% for f in previous_fields %}{{ f.as_hidden }}{% endfor %}

The latest stable release for the forms module can be obtained by:


Note: The BoundFormWizard class can only handle regular FormSets and not ModelFormSets. I have ModelFormWizard class that I'll be adding to a future release that can handle simple Models.

Monday, 13 July 2009

Flash Back

Late last year Solaris 10 Update 6 was released and included the long waited for ZFS root capability. Unfortunately for many customers using Jumpstart to build their systems it also meant they had to stop using Flash Archives as Sun explicitly stated that they were incompatible. Solaris 10 Update 7 didn't fix this either and zfs-discuss forum discussions seemed to indicate it would not be available until Solaris 10 Update 8 and may be available as a patch for earlier releases.

Well the day has come and the miniroot patches are now available to download from SunSolve:

Sparc
x86
My own build environment skipped S10U6 and went to U7 recently and had to put up with the loss of flash archive builds with the knowledge it would be reinstated soon. I'll be testing these patches in the next week and will report back here with the results.

Update 2009.08.20: Sun have posted some preliminary documentation on how to use ZFS and Flash.

Saturday, 30 May 2009

New Solaris PatchFinder tool

Anyone who has ever used the existing Solaris patch search tool will know how limited it is. Well Sun have released a much improved search page called Software Update Finder. Gerry Haskins has detailed blog about its new capabilities which include:
  • Filtering results by OS release and architecture.
  • Limiting search results to Security and/or Recommended patches.
  • Searching for patches that fix a particular CR or BugId.
See Gerry's article for more features. This is just the initial release and there are plans to enhance it further in the future. Let Sun know what you want the tool to do.

Tuesday, 26 May 2009

Python ipaddr performance

Last weekend while I was cleaning up my IP address summarization script (I added a setup.py, created a Cheese Shop entry and a downloadable archive) I had a look at the state of IP address manipulation in Python and found a new module called ipaddr. What sparked my interest in this module was that it had already been integrated into upcoming Python 2.7 and 3.1 as a standard library.

It seemed to contain all the functionality of IPy but with much cleaner code. It also has a function called collapse_address_list() that is similar to my summarize function but it can handle a list of non-contiguous networks and IP addresses and collapse them down.

When I wrote my summarize() function I spent quite a while optimizing the algorithm so that it can handle large address ranges in a reasonable amount of time. For example, on my development box it can summarize the two worst case ranges: IPv4 0.0.0.0 to 255.255.255.254 in 0.1s and IPv6 :: to ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe in 0.2s.

I had to see how well ipaddr performed so I wrote a little benchmarking script that summarized a /24. The results were very poor with it taking 64.27 seconds to perform 1000 runs. I then ported my summarize() code to use ipaddr and modified collapse_address_list() to use it. The result was a 50 times improvement in performance (1000 runs took 1.21 seconds).

ipaddr is developed by Google and the coders use Reitveld for reviewing patches. So I've submitted my patches there. Feel free to review and comment on the code.

Here's hoping that they are accepted and benefit everyone by making it into the next release(s) of Python!

Sunday, 24 May 2009

Django Serializer Updates

I've had a couple of emails and forum posts where users were having difficulty with my serialization module. The problems mostly centered around installing it correctly.

I did a little work tonight to clean up the installation side of things. As a result you can now find the module in the Cheese Shop.

The latest stable release for the serialization module can also be obtained by:
The source tree has been moved around a little to accommodate these changes and can be found here.

There were no new features or bug fixes made but I have a few interesting tickets from users that I'll be reviewing over the coming weeks.