Django Forms I: Custom fields and widgets in detail

Comments

On Thursday September 8th I copresented with Daniel Greenfeld my first talk “Advanced Django Form Usage” at DjangoCon.us 2011. It was my first talk for many reasons. I had never spoken in front of such a large audience before, less in English and this was also my first Python talk. If you haven’t seen the video of the talk and the slides, you probably want to, because this post will try to extend, clarify and recap it somehow. Also this will be my official erratum for things that were not exactly true or right that appeared in the slides

Some people really loved the talk and came after it to comment it with me and ask some questions. By that time, I was already thinking that the topic did deserve its own series of posts. Gabriel Hurley, Django committer and documentation specialist, stated:

Apparently some core developers were asking to use the code examples and a transcript from the talk as a starting point for this task. Well, I wasn’t sure if the transcript would be good enough, many things were left to say, but I agreed with Gabriel that it’s a good starting point to base docs on, which is better than starting from scratch. I still feel this necessity of writing these series of posts, which will hopefully be a better starting point than the transcript. I’ve been extremely busy since I gave the talk, but now I happen to have some spare time, so let’s start.

This first post will start with some advanced things: creating custom form fields, custom widgets and how to get the most out of them. Beware that you need to have a good grasp of Django forms to grok these concepts.

Read More

Django-uni-form 0.9.0 is out [security fix]

Comments

Version 0.9.0 is out and you should update because of security reasons. An XSS bug has been fixed, thanks to Charlie Denton for reporting it. If you are using django-uni-form and a form field that renders the input of a field as part of the error message without sanitizing it, such as ChoiceField, you are vulnerable to it. This is because errors are rendered using |safe filter.

This has been addressed as fast as possible. Fixes for previous versions might come in the soon future. PyPi package has been update so you can do:

pip install --upgrade django-uni-form

This is the commit that introduced the security bug, as you can see it affects version 0.7.0 and forward versions.

I want to thank every contributor and user that has made this version rock even more than previous ones.

Bug fixes

It’s got support for show_hidden_initial, Fieldset’s legends internationalization, error_css_class and required_css_class. MultiField layout object has fixed markup and has been optimized.

Performance boost

The project has seen several performance tune ups, related to templates handling, that make it run blazing fast. You can run now django-uni-form without template caching only one second slower than the cached version.

Read More

New kung-fu in django-uni-form 0.8.0

Comments

This won’t be a new official release announcement as Daniel already did the honors. I’m now the co-lead developer of django-uni-form and in this post I will try to go over some examples that teach you new kung-fu techniques. But before doing so, let me emphasize how cool this project is and how many new nice features are packed in the new version 0.8.0. If you like DRY principles and don’t think your Django forms are DRY enough using built-in filters, you should check it! if you haven’t yet.

To explain some of the new features, let’s use a real form and a real example, so it’s easier to follow how django-uni-form works and what has been enhanced.

The following form will be used from now onwards to exemplify the new features in django-uni-form. I’m using different types of form fields to demonstrate how django-uni-form can work with any built-in widget or form field or any other custom field that you have defined. That is, django-uni-form plugs well with other form apps.

Read More

Be careful how you use static variables in forms

Comments

Working on django-uni-form I came across with a weird situation and it took me some time to figure out what was going on. I wouldn’t say it was a bug, it was more a misuse or a documentation problem. After that, I realized other coders make the same mistake that was affecting us, so I thought about writing an article for warning Python/Django programmers.

If you are building a Django application in which you add attributes to a form, that are not form fields, like in this example:

class ExampleForm(forms.Form):
    description = forms.CharField(
        label = u"Short description",
        max_length = 40,
    )
    
    type_of_form = 'dangerous'

You should know that every attribute that is not a form field, such as type_of_form, is static or a class-wide variable. Let’s see what this means and please stay with me till the end, don’t switch channel. If you handle a form instance in one of your views and change type_of_form value:

Read More

Using jQuery templating ICanHaz.js with Django

Comments

When working on a Django project with an important part of the user experience based on AJAX, you better use a frontend templating language. The same way Django has a templating language that we use to populate values easing your coder’s life, jQuery has client side alternatives. One of these plugins and my personal favorite is ICanHaz.js created by @HenrikJoreteg. It’s only 4.4 Kb.

ICanHaz.js syntax will be very familiar to Django devs, because a variable is defined using double curly brackets {{ variable }}. But I will not enter into details, the project has very easy to follow setup instructions and code examples.

When people start using ICanHaz.js in their Django templates, they have a very hard first time trying to get it to work. The problem is simple, Django and ICanHaz.js share the same variable definition, so Django interprets the script templates, breaking them.

Read More

Django PositiveNormalizedDecimalField

Comments

Some weeks ago I was working on a Django project that was using some FloatFields where they should not be used, the database backend was Postgres 8.4. If you are not aware of it, FloatFields are turned into double precission types, that means 64-bit floating-point numbers. Those fields were storing values that didn’t need such precission. For example I don’t think you need them to store items’ weights, do you?

I migrated those fields to DecimalFields using an average (max_digits=7, decimal_places = 2), which means a total of 7 digits, with 2 decimals. Of course I had to migrate the database, doing some manual alters, as Django-south was not being used. By default DecimalFields render the number with all its decimal digits, which was not what I was looking for. I needed a decimal field that:

  • By default render decimal values normalized using non-scientific notation. See Decimal("10.400").normalize()
  • Only allowed positive values
Read More