How to disable auto strip in Charfield in Django
Table of Contents
In Django, when edit field in admin page or post data to forms, the leading and tailing whitespace in CharField
and TextField
are removed.
The reason is strip=True
parameter in forms.CharField
, which is added in Djagno 1.9. You can see the discussion in django tiket #4960 and here is source code. models.CharField
and models.TextField
use formfield()
to create form to interact with user, then both of them eventually create a forms.CharField
It only affect the value return from forms, you can still update model manually and calling save()
to save it with spaces.
Normally, this feature help us to keep text field clean. But sometimes you may want to get the original value, and here are three different solutions:
Suppose we have this Test
model.
# models.py
class Test(models.Model):
char = models.CharField(max_length=20)
text = models.TextField()
Change ModelAdmin #
# admin.py
TestAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.name in ['char', 'text']:
kwargs['strip'] = False
return super().formfield_for_dbfield(db_field, request, **kwargs)
This method tackles the problem by overriding fields’ default fromfiled
method.
Define Custom Form #
# forms.py
class CustomForm(forms.ModelForm):
char = forms.CharField(strip=False)
text = forms.CharField(strip=False, widget=forms.Textarea)
class Meta:
model = Test
exclude = []
# admin.py
TestAdmin(admin.ModelAdmin):
form = CustomForm
Now when edit data in admin panel, the whitespace is not removed anymore.
Use Custom Field #
You can also use your custom field in models.py
. For example:
# models.py
from django.db.models import TextField
class NonStrippingTextField(TextField):
def formfield(self, **kwargs):
kwargs['strip'] = False
return super(NonStrippingTextField, self).formfield(**kwargs)
class Test(models.Model):
text = NonStrippingTextField()
==
REST Framework #
If you use Django REST framework to edit data, you only need to change the serializer.
class TestSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Test
fields = '__all__'
extra_kwargs = {"char": {"trim_whitespace": False},
"text": {"trim_whitespace": False}}