How can I allow django admin to set a field to NULL?

25,081

Solution 1

Try to overwrite the save() method of the Model, to check for empty values:

class MyModel(models.Model):

    my_nullable_string = models.CharField(max_length=15, null=True, blank=True)

    def save(self, *args, **kwargs):
         if not self.my_nullable_string:
              self.my_nullable_string = None
         super(MyModel, self).save(*args, **kwargs)

Solution 2

This section in the docs makes it sound like you can't set a string-based field to NULL through the admin; it will use the empty string. This is just the way Django does it. It will work for other types of fields.

You'll either have to hack on the admin script or else decide it doesn't really need to be NULL in the database; an empty string is OK.

Solution 3

try this code, here Language.subregion hass null=True this code overwrites admin form settings (LanguageAdmin) and sets "subregion" field property - required to False

from app.models import Language
from django.contrib import admin

class Language(models.Model):
    subregion = models.ForeignKey(SubRegion, null=True)
    code = models.CharField(max_length=10, unique=True)

class LanguageAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        form = super(LanguageAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['subregion'].required = False
        return form

admin.site.register(Language, LanguageAdmin)

Solution 4

Usually, when you pass both null=True and blank=True, if you leave the field blank in the admin, Django will use NULL for its value.

EDIT:

as agf explains in his answer, this is true for all types except CharField and TextField.

Solution 5

I often use Django just for the Admin and need to preserve a lot of NULLs in the db. I use this snippet to set all empty strings on a particular object to NULL.

def save(self, *args, **kwargs):
    for var in vars(self):
        if not var.startswith('_'):
            if self.__dict__[var] == '':
                self.__dict__[var] = None
    super(MyModel, self).save(*args, **kwargs)
Share:
25,081
Hubro
Author by

Hubro

Code enthusiast!

Updated on July 09, 2022

Comments

  • Hubro
    Hubro almost 2 years

    I've set my Model field to null=True, which allows NULL in MySQL, but I can't seem to assign NULL to the field through Django Admin. I've tried also setting blank=True, but that just sets the field to an empty string. Following this didn't work either, as the field value was set to "None", the string.

    Any ideas?

  • Caumons
    Caumons over 10 years
    +1 If the field you are dealing with is set to be unique, then the only option is "hacking the admin"
  • Anoyz
    Anoyz over 8 years
    I'm using null in a ForeignKey, and it still doesn't allow it to be null. So it's not a string-related issue.
  • toxefa
    toxefa over 7 years
    I'm coming to this late but this is crazy!! When you have unique=True and blank=True this glaring problem with the Django admin will slip through Test Client and model unit tests, rearing it's head only when someone tries to leave out a unique field more than once. IMO this is basically a bug seeing as in every case except the admin, null=True + no default value means a NULL value in the DB.
  • Vallie
    Vallie almost 6 years
    setting default=None helps
  • Alexander Kleinhans
    Alexander Kleinhans about 5 years
    Dude, null and an empty string are not the same thing. One breaks and unique constraint and the other doesn't. Jesus christ. Going around lazily saying, "hey it worked for my stupid unit test" is why horrible software breaks in production.
  • Danny Staple
    Danny Staple about 4 years
    I needed to combine this with the get_form answer from pymen for this to work with blank=True, unique=True fields.
  • Jatin Goyal
    Jatin Goyal about 4 years
    this is true except for CharField, TextField and ArrayField.
  • Matt Dodge
    Matt Dodge about 4 years
    Seems to me (based on the code in that commit and some testing) that this will only affect DB connections that have interprets_empty_strings_as_nulls set to True, so not exactly fixed for all CharFields and not fixed for the OP's use case with MySQL either.
  • JHS
    JHS over 3 years
    Note: I had to do this in clean instead of save for a ModelAdmin form.
  • Daniel Lema
    Daniel Lema over 2 years
    That fixes the issue for the record level CRUD form, but not for the multirow or table level form... Any idea on how to fix that also? Thx
  • pymen
    pymen over 2 years
    @DanielLema you may try to override def get_changelist_form or whatever method is used by Django to show the form