Opened 8 years ago

Closed 7 years ago

Last modified 2 months ago

#9590 closed Uncategorized (wontfix)

CharField and TextField with blank=True, null=True saves u'' instead of null

Reported by: romke Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Normal Keywords: charfield, textfield, null
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no


Create model and form:

class Test(models.Model):
    testfield = models.CharField(max_length=20, null=True, blank=True)
    testfield2 = models.TextField(null=True, blank=True)
class NullCharFieldForm(forms.ModelForm):
  class Meta:
    model = Test
    fields = ('testfield', 'testfield2',)

Now create object from POST-alike data (empty input or textarea = ""):

>>> form = NullCharFieldForm({'testfield':'', 'testfield2': ''})
>>> form.is_valid()
>>> obj =
>>> obj.testfield
>>> obj.testfield2

form validates as it should with blank=True but it stores u"" in object fields and in DATABASE :/

result should be:

>>> obj.testfield
>>> obj.testfield is None

Patch + tests attached, it's created on 1.0.X branch, it passes against model_forms and forms (regression) tests.

Attachments (1)

char-text-field-null-value-save-null.patch (3.2 KB) - added by romke 8 years ago.
patch + tests

Download all attachments as: .zip

Change History (10)

Changed 8 years ago by romke

patch + tests

comment:1 Changed 8 years ago by ramiro

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I think this behavior ir related to the convention used by Django for CharField's and TextField's with no value, the rationale is explained in the section of documentation that describes the null field option:

comment:2 Changed 8 years ago by mtredinnick

  • Resolution set to wontfix
  • Status changed from new to closed

This is by design and fully documented. If you want to save NULLs in a text-based field, you'll need to create your own Field subclass. Changing the existing Django behaviour would be backwards-incompatible.

comment:3 Changed 7 years ago by mightyhal

  • Component changed from Forms to Database layer (models, ORM)
  • Has patch unset

I agree that it's pretty annoying that django forces for empty string fields, even when null=True, blank=True is set. Following mtredinnick's suggestion (and some teeth grinding), here's how to subclass a CharField to make it store NULL:

from django.db import models

class CharNullField(models.CharField):
	description = "CharField that stores NULL but returns ''"
	def to_python(self, value):
		if isinstance(value, models.CharField):
			return value 
		if value==None:
			return ""
			return value
	def get_db_prep_value(self, value):
		if value=="":
			return None
			return value

comment:4 Changed 7 years ago by contact_django@…

  • Has patch set
  • Patch needs improvement set
  • Resolution wontfix deleted
  • Status changed from closed to reopened

The behavior is contrary to documentation.
When a field has null=True, django should store a NULL value, as documented.
Documentation says "Avoid using null on string-based fields such as CharField and TextField unless you have an excellent reason." When you have a legacy database, you may be in a situation when you don't have the choice. This is my case. Actually I even have a database integrity check field<>[[BR]]

If you really really don't want to support null=True for these kind of fields, you should fix the documentation and issue an error when a null=True is found in a CharField.

comment:5 Changed 7 years ago by ubernostrum

  • Resolution set to wontfix
  • Status changed from reopened to closed

Don't reopen a ticket which has been closed as "wontfix" by a committer. If you disagree, bring up the issue on the django-developers mailing list.

comment:6 Changed 3 years ago by alepane

  • Easy pickings unset
  • Severity set to Normal
  • Type set to Uncategorized
  • UI/UX unset

If you need a nullable CharField, you can use this small app that I made

comment:7 Changed 17 months ago by halfnibble

Thanks goodness for Google search!

This inconsistency was driving me mad. As a new django dev, I thought I was doing something wrong. Good to know it's not me--it's backward's compatibility. From a long, long, long time ago. This should be mentioned with a bright red warning label in the documentation.

comment:8 Changed 17 months ago by jarshwah

It is documented:

Avoid using null on string-based fields such as CharField and TextField because empty string values will always be stored as empty strings, not as NULL. ... the Django convention is to use the empty string, not NULL.

comment:9 Changed 2 months ago by jdufresne

To anyone reading this ticket looking for a solution. The following commit may provide an alternative path to solve the same problem.

Relevant ticket: #4136

Note: See TracTickets for help on using tickets.
Back to Top