CharFields and children defaulting to emtpy string

12 views
Skip to first unread message

Gary Wilson

unread,
Sep 11, 2006, 2:25:28 PM9/11/06
to Django developers
using the example model:

class Name(models.Model):
name = models.CharField(maxlength=100)

when making a new Name object...
>>> a=Name()
>>> a.save()
>>> a
<Name: Name object>
>>> a.name
''

The name field does not have blank=True or null=True set, but yet I am
able to create a new Name object using no parameters (because
CharFields and children are defaluting to empty string). Is this the
intended behavior?

gabor

unread,
Sep 11, 2006, 3:05:00 PM9/11/06
to django-d...@googlegroups.com

hi,

yes, (unfortunately) it is.

the models do not validate their input.

you will have to use a manipulator (Name.AddManipulator) to validate
your input (and then save the object).

making the models validation-aware is planned, but not done yet.

gabor

Gary Wilson

unread,
Sep 13, 2006, 3:54:34 PM9/13/06
to Django developers
gabor wrote:
> yes, (unfortunately) it is.
>
> the models do not validate their input.
>
> you will have to use a manipulator (Name.AddManipulator) to validate
> your input (and then save the object).
>
> making the models validation-aware is planned, but not done yet.

But I am not talking about validating my input here. I just don't want
input to be inserted for me. For example, non-specified IntegerField
attributes don't defalut to zero. So why then do non-specified
CharField attributes default to empty string?

Don Arbow

unread,
Sep 13, 2006, 4:56:30 PM9/13/06
to django-d...@googlegroups.com
On Sep 11, 2006, at 11:25 AM, Gary Wilson wrote:
> The name field does not have blank=True or null=True set, but yet I am
> able to create a new Name object using no parameters (because
> CharFields and children are defaluting to empty string). Is this the
> intended behavior?

Yes, from the documentation:

http://www.djangoproject.com/documentation/model_api/#null

"Note that empty string values will always get stored as empty
strings, not as NULL -- so use null=True for non-string fields such
as integers, booleans and dates.

Avoid using null on string-based fields such as CharField and Text
Field unless you have an excellent reason. If a string-based field
has null=True, that means it has two possible values for "no
data":NULL, and the empty string. In most cases, it's redundant to
have two possible values for "no data"; Django convention is to use
the empty string, not NULL."

The reason that integers without values insert as null is because
their empty_strings_allowed value is False. Most non-string fields in
Django have this set to False, text fields have it set to True, in
order to assert the behavior described in the documentation. To
override this behavior, you need to set a default value.

Note that when gabor mentioned validation, he was talking about your
comment about not setting blank=True. Blank=True/False is a framework
constraint, null=True/False is a database constraint.

Don

Gary Wilson

unread,
Sep 13, 2006, 10:09:07 PM9/13/06
to Django developers
Don Arbow wrote:
> Yes, from the documentation:
>
> http://www.djangoproject.com/documentation/model_api/#null
>
> "Note that empty string values will always get stored as empty
> strings, not as NULL -- so use null=True for non-string fields such
> as integers, booleans and dates.
>
> Avoid using null on string-based fields such as CharField and Text
> Field unless you have an excellent reason. If a string-based field
> has null=True, that means it has two possible values for "no
> data":NULL, and the empty string. In most cases, it's redundant to
> have two possible values for "no data"; Django convention is to use
> the empty string, not NULL."

Ok, after some trial and error, I see that if you have null=True on a
CharField, it will use NULL instead of empty string. This is what I
needed because in my model I have a field that I want to be optional
but unique. This is not possible if you don't put null=True for the
field because Django will try to use empty string by default.

Out of curiosity, any one know for what reason using empty strings for
CharFields is the Django convention? Technically, isn't an empty
string still data? Isn't it a bit confusing that some fields get
default values and others do not? Explicit better than implicit?

Marc D.M.

unread,
Sep 13, 2006, 11:53:07 PM9/13/06
to django-d...@googlegroups.com
On Thu, 2006-09-14 at 02:09 +0000, Gary Wilson wrote:

> Out of curiosity, any one know for what reason using empty strings for
> CharFields is the Django convention? Technically, isn't an empty
> string still data? Isn't it a bit confusing that some fields get
> default values and others do not? Explicit better than implicit?
>

Well, storing NULL vs Empty-string should consume just about the same
amount of data or the difference should be insignificant.

However, I think it empty-string was used due to the variations in how
databases handle NULL values in strings and how to handle the strings
['NULL','Null','nul']

not sure if I read that somewhere or came up with it on my own
though. :)

/Marc DM

Don Arbow

unread,
Sep 14, 2006, 12:44:34 AM9/14/06
to django-d...@googlegroups.com
On Sep 13, 2006, at 7:09 PM, Gary Wilson wrote:
>
> Out of curiosity, any one know for what reason using empty strings for
> CharFields is the Django convention? Technically, isn't an empty
> string still data? Isn't it a bit confusing that some fields get
> default values and others do not? Explicit better than implicit?

My guess is that you need less code when you can assume that all text
columns in the database contain strings. Python strings are first-
class objects and so have instance methods you can call by appending
the function call onto the variable. If you had nulls returned from
those text columns, then every time you wanted to execute a string
function, you'd have to test for None, then convert it. Then with a
test, you may waste code AND cycles because if you code

if not string:
string = ''
string.split(...)

half the time you may be assigning an empty string to a variable that
already contains an empty string.

That's one reason I can think of, there may be others.

Don


Malcolm Tredinnick

unread,
Sep 15, 2006, 10:00:54 PM9/15/06
to django-d...@googlegroups.com
Hey Gary,

On Thu, 2006-09-14 at 02:09 +0000, Gary Wilson wrote:

[...]


> Ok, after some trial and error, I see that if you have null=True on a
> CharField, it will use NULL instead of empty string. This is what I
> needed because in my model I have a field that I want to be optional
> but unique. This is not possible if you don't put null=True for the
> field because Django will try to use empty string by default.
>
> Out of curiosity, any one know for what reason using empty strings for
> CharFields is the Django convention? Technically, isn't an empty
> string still data? Isn't it a bit confusing that some fields get
> default values and others do not? Explicit better than implicit?

Looking at this from a database persepctive, it's bad, I agree (NULLs
and empty strings are different animals and they should be able to
co-exist). However, looking at it from a web framework perspective, a
decision has to be made, so Django's approach is not illogical. To
explain...

Think about how the data is entered: through a web form (the admin
interface, or a custom form). Now, how do you differentiate between an
explicit empty string and a "no data entered and so it should be NULL"
field? With web entry, you can't, so Django chooses to default to using
empty strings everywhere.

When I first started using Django, this drove me nuts. Why were the
developers being so righteous about good web practices and then paying
no heed to good databases in this fashion (I thought)? But, when you
think about it, it's a hard problem -- differentiating between the two
cases for web entry is tough. So the compromise is not unreasonable.
Remembering my own reaction, though, I can certainly sympathise with the
"are they evil?" thoughts that might occasionally flit through peoples'
heads when encountering this.

NULLs are still allowed in character fields, so legacy data is
supported. Evilness is averted. :-)

Regards,
Malcolm

DavidA

unread,
Sep 16, 2006, 7:34:16 AM9/16/06
to Django developers

Malcolm Tredinnick wrote:
> When I first started using Django, this drove me nuts.

I had the same reaction, but also understand there isn't a great way to
handle it. In Microsoft's SQL Enterprise Manager, you can enter Ctrl-0
in a field and it will set that field to NULL. I'm thinking about doing
something like this in one of my Django forms since I need to support
both an empty string _and_ a NULL input so I want an explicit way to
differentiate between the two. A control character doesn't work well
for browser input, but I may end up treating an empty string as NULL
and force the user to put "" if they really want a blank string (which
in this case is the exception, not the norm).

I don't know if something like that is a reasonable solution for Django
or not, but I know it would come in handy in a number of situations.

-Dave

gabor

unread,
Sep 16, 2006, 10:28:48 AM9/16/06
to django-d...@googlegroups.com
DavidA wrote:
>
> Malcolm Tredinnick wrote:
>> When I first started using Django, this drove me nuts.
>
> I had the same reaction, but also understand there isn't a great way to
> handle it. In Microsoft's SQL Enterprise Manager, you can enter Ctrl-0
> in a field and it will set that field to NULL. I'm thinking about doing
> something like this in one of my Django forms since I need to support
> both an empty string _and_ a NULL input so I want an explicit way to
> differentiate between the two. A control character doesn't work well
> for browser input, but I may end up treating an empty string as NULL
> and force the user to put "" if they really want a blank string (which
> in this case is the exception, not the norm).

assuming that you want to differentiate between:

- the user did not fill in the data
- the user's input was ""

wouldn't it be better to represent this in html as a checkbox+an input
field?

and by default have the checkbox unselected, and the input-field disabled.
and then if the user checks the checkbox, enable the field.

and then in the view code, simply check the checkbox's value and set the
field to null or to what-was-in-the-input-field.

gabor

Malcolm Tredinnick

unread,
Sep 16, 2006, 8:09:09 PM9/16/06
to django-d...@googlegroups.com
On Sat, 2006-09-16 at 16:28 +0200, gabor wrote:
> DavidA wrote:
> >
> > Malcolm Tredinnick wrote:
> >> When I first started using Django, this drove me nuts.
> >
> > I had the same reaction, but also understand there isn't a great way to
> > handle it. In Microsoft's SQL Enterprise Manager, you can enter Ctrl-0
> > in a field and it will set that field to NULL. I'm thinking about doing
> > something like this in one of my Django forms since I need to support
> > both an empty string _and_ a NULL input so I want an explicit way to
> > differentiate between the two. A control character doesn't work well
> > for browser input, but I may end up treating an empty string as NULL
> > and force the user to put "" if they really want a blank string (which
> > in this case is the exception, not the norm).
>
> assuming that you want to differentiate between:
>
> - the user did not fill in the data
> - the user's input was ""
>
> wouldn't it be better to represent this in html as a checkbox+an input
> field?

Remember that we are trying to produce normal looking HTML pages here.
How many HTML forms have you filled out where you need to also check a
box saying "I want to use this input box"? That is exposing underlying
database representation to the end-user and if you put yourself in the
shoes of the user, it's just going to seem odd (and very off-putting).

Forcing a big change like that in the way forms naturally work is a
really leaky abstraction and it's why a choice had to be made. If
somebody really wants empty strings to be stored as NULL, they can
override their model's save method and fix it up there (there was
somebody posting on django-users last month about doing exactly that).
If, for some reason, the data entry person really is in a position to
make the decision, then implement something like the ctrl-0 trick Dave
Avraamides mentioned yesterday, or do the checkbox manually. But it's
not something where the person using your form should have to care, by
and large.

Cheers,
Malcolm

Malcolm Tredinnick

unread,
Sep 16, 2006, 8:14:28 PM9/16/06
to django-d...@googlegroups.com
Hi Gabor,

OK, ignore my post -- you were offering an alternative to David's idea,
not proposing a universal change.

/me backs sheepishly away from the keyboard and goes to get some coffee
and wake up.

Malcolm


DavidA

unread,
Sep 17, 2006, 3:54:43 PM9/17/06
to Django developers

gabor wrote:
>
> assuming that you want to differentiate between:
>
> - the user did not fill in the data
> - the user's input was ""
>
> wouldn't it be better to represent this in html as a checkbox+an input
> field?
>
> and by default have the checkbox unselected, and the input-field disabled.
> and then if the user checks the checkbox, enable the field.
>
> and then in the view code, simply check the checkbox's value and set the
> field to null or to what-was-in-the-input-field.

gabor,

That's certainly more explicit but makes for a busier UI and also makes
it more difficult to reuse a standard FormWrapper in the template.
After thinking about this more, I can't come up with a case where the
input value should ever be an empty string so I think always mapping an
empty string to NULL on save() will work just fine. Just for some
background, the use case here is that for a financial instrument editor
(stock, bond, swap, etc.) there are certain fields that come from a
third party data vendor but occasionlly the user will wish to override.
Other fields are only maintained internally so they can be directly
edited. For the overridable fields, if the user enters a new value, it
will become the effective value for that field, but if they clear the
field, it reverts back to the default value.

For my specific case, I don't think treating empty fields as NULL will
create a problem (and if it does I can use the "" as an easy
workaround).

Thanks for the ideas, though.
-Dave

Gary Wilson

unread,
Sep 18, 2006, 12:24:51 AM9/18/06
to Django developers
David and I have both introduced use cases where defaulting to empty
string have caused problems. What are some use cases where an empty
string would need to be used instead of NULL?

IMO, all FormFields should act the same and default to NULL. If you
want the database field to default to something other than NULL, then
you can use the "default" parameter in the model's definition. Then,
just as you might want to use default=0 for IntegerFields, you might
want to use default='' for CharFields.

Gary Wilson

unread,
Sep 23, 2006, 11:29:36 AM9/23/06
to Django developers
Malcolm Tredinnick wrote:
> Think about how the data is entered: through a web form (the admin
> interface, or a custom form). Now, how do you differentiate between an
> explicit empty string and a "no data entered and so it should be NULL"
> field? With web entry, you can't, so Django chooses to default to using
> empty strings everywhere.

So I understand that Django made the choice to default to empty
strings, but what I am really trying to learn is why.

Reply all
Reply to author
Forward
0 new messages