Django TextField and CharField is stripping spaces and blank lines
Asked Answered
S

6

22

I just researched my "bug" and it turned out to be a new feature in Django 1.9 that CharFields strip spaces by default : https://docs.djangoproject.com/en/1.9/ref/forms/fields/#django.forms.CharField.strip

The same seams to apply to text fields TextField.

So I found out why Django suddenly behaves differently than before, but is there an easy way to restore the previous default for auto generated admin forms?

I would like to NOT strip spaces while still using the auto generated form from the admin. Is that still possible?

Sleeping answered 17/8, 2016 at 11:46 Comment(0)
L
18

If you are looking for a text/char field and do not want it to strip white spaces you can set strip=False in the constructor method of a form and then use the form in the admin

class YourForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(YourForm, self).__init__(*args, **kwargs)
        self.fields['myfield'].strip = False

    class Meta:
        model = YourModel
        fields = "__all__"

You can then use this form in the admin by specifying form=YourForm in the admin.py file.

Laverty answered 19/6, 2018 at 13:29 Comment(3)
i already answered that question myself with a more compact syntax nearly a year ago :)Sleeping
I am not sure how your solution will work in case I want the field from the model in the model form rather than defining a field, just to ensure it has all the validation checks defined in the model. Your 1-year-old solution didn't work for me so I came up with this solution and posted it, so it might help somebody. :)Laverty
Good point actually - reusing the generated field rather than redefining it, might save some work here in case the field is more complicated than my old usecase.Sleeping
C
12

Try using this:

# fields.py
from django.db.models import TextField


class NonStrippingTextField(TextField):
    """A TextField that does not strip whitespace at the beginning/end of
    it's value.  Might be important for markup/code."""

    def formfield(self, **kwargs):
        kwargs['strip'] = False
        return super(NonStrippingTextField, self).formfield(**kwargs)

And in your model:

class MyModel(models.Model):
    # ...
    my_field = NonStrippingTextField()
Charleencharlemagne answered 20/11, 2016 at 21:23 Comment(2)
Thats a nice idea .. will check that next time i run into this problem :)Sleeping
This worked well to me! Couldn't find it so I posted Is there a way to disable Django Admin removing trailing spaces in TextField strings? and was marked as a dupe of this.Cerracchio
K
7
strip=False 

in the model field for CharFields.


Django TextField do not support this stripping feature so you have to do it on your own. You can use the strip method.

abc.strip()
Kennedy answered 17/8, 2016 at 12:21 Comment(2)
According to the docs the strip parameter is only valid for the form field but not for the model field .. and i of course tried: TypeError: __init__() got an unexpected keyword argument 'strip'Sleeping
and like i said above i want to remove the strip feature which is the default starting with Django 1.9 - i basically like it, but for my current project i want to have spaces NOT stripped awaySleeping
S
5

Seems like the best way to handle this is to create a custom admin form like this:

class CustomForm(forms.ModelForm):
    my_field = forms.CharField(strip=False, widget=forms.Textarea)

    class Meta:
        model = MyModel
        exclude = []

This will create a default form with just my_field overwritten with its non stripped version. )this has to be set in the corresponding admin of course. If anybody knows an even simpler version. Please tell me!

Sleeping answered 18/8, 2016 at 14:21 Comment(0)
F
4

You can also achieve this by modifying ModelAdmin.

Overridding formfield_for_dbfield function and setting kwargs['strip'] = False for title field will disable auto trim for it.

@admin.register(Example)
class ExampleAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        if db_field.name == 'title':
            kwargs['strip'] = False
        return super().formfield_for_dbfield(db_field, request, **kwargs)

Ref: https://www.aaronoellis.com/articles/allow-whitespace-to-be-a-valid-charfield-value-in-django-admin

Feign answered 24/6, 2021 at 8:59 Comment(0)
M
2

I was having this issue with django-rest model serializer. The data in my text field was stripped of white space. So if you are trying to do this on the serializer level, you can specify the whitespace param on CharField serializer. Here is the source code signature.

And here is the rest-docs on CharField

class SomeSerializer(serializers.ModelSerializer):
    content = serializers.CharField(trim_whitespace=False)

    class Meta:
        model = YourModel
        fields = ["content"]
Multimillionaire answered 26/11, 2018 at 22:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.