11

In the model I set:

class Task(models.Model):
    EstimateEffort = models.PositiveIntegerField('Estimate hours',max_length=200)
    Finished = models.IntegerField('Finished percentage',blank=True)

But in the web page, if I didn't set a value for the Finished field, it is showing an error This field is required. I tried null=True and blank=True. But none of them worked. So could you please tell me how can I make a field allowed to be empty.

I have found that there is a attribute empty_strings_allowed, i set it to True, but still the same, and i subclass the models.IntegerField. It still can not work

class IntegerNullField(models.IntegerField):
    description = "Stores NULL but returns empty string"
    empty_strings_allowed =True
    log.getlog().debug("asas")
    def to_python(self, value):
        log.getlog().debug("asas")
        # this may be the value right out of the db, or an instance
        if isinstance(value, models.IntegerField):
            # if an instance, return the instance
            return value
        if value == None:
            # if db has NULL (==None in Python), return empty string
            return ""
        try:
            return int(value)
        except (TypeError, ValueError):
            msg = self.error_messages['invalid'] % str(value)
            raise exceptions.ValidationError(msg)

    def get_prep_value(self, value):
        # catches value right before sending to db
        if value == "":
            # if Django tries to save an empty string, send to db None (NULL)
            return None
        else:
            return int(value) # otherwise, just pass the value
jimwan
  • 1,086
  • 2
  • 24
  • 39

3 Answers3

13

Use

Finished = models.IntegerField('Finished percentage', blank=True, null=True)

Read https://docs.djangoproject.com/en/1.4/ref/models/fields/#blank:

null is purely database-related, whereas blank is validation-related.

You might have defined the field without null=True first. Changing that in the code now won't change the initial layout of the database. Use South for database migrations or change the database manually.

Matthias
  • 12,873
  • 6
  • 42
  • 48
4

On a form you could set required=False on the field:

Finished = forms.IntegerField(required=False)

Or to avoid redefining the field on a ModelForm,

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['Finished'].required = False
    #self.fields['Finished'].empty_label = 'Nothing' #optionally change the name
Community
  • 1
  • 1
CJ4
  • 2,485
  • 3
  • 26
  • 29
  • models can be: Finished = models.IntegerField(blank=True, null=True) – CJ4 Dec 14 '12 at 09:57
  • do you already have a form? because when you specify fields on a form the fields are required by default then it doesn't matter that you made it nullable in the models because it is required when it is represented in the html. But you can not make a form field optional and the field on the model required – CJ4 Dec 14 '12 at 09:59
2

Maybe a default value is needed

finished = models.IntegerField(default=None,blank=True, null=True)
Qiang Jin
  • 4,427
  • 19
  • 16