(Джанго) Обрезать пробелы в charField - PullRequest
16 голосов
/ 18 февраля 2011

Как мне убрать пробелы (обрезку) с конца charField в Django?

Вот моя модель, как вы можете видеть, я пытался вставить чистые методы, но они никогда не запускались.

Я также пытался сделать name.strip(), models.charField().strip(), но они тоже не работают.

Есть ли способ заставить charField автоматически обрезаться для меня?

Спасибо.

from django.db import models
from django.forms import ModelForm
from django.core.exceptions import ValidationError
import datetime

class Employee(models.Model):
    """(Workers, Staff, etc)"""
    name                = models.CharField(blank=True, null=True, max_length=100)

    def save(self, *args, **kwargs):
        try:
            # This line doesn't do anything??
            #self.full_clean()
            Employee.clean(self)
        except ValidationError, e:
            print e.message_dict

        super(Employee, self).save(*args, **kwargs) # Real save

    # If I uncomment this, I get an TypeError: unsubscriptable object
    #def clean(self):
    #   return self.clean['name'].strip()

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Employees'

    class Admin:pass


class EmployeeForm(ModelForm):
    class Meta:
        model = Employee

    # I have no idea if this method is being called or not  
    def full_clean(self):       
        return super(Employee), self.clean().strip()
        #return self.clean['name'].strip()

Отредактировано: обновлен код до последней версии.Я не уверен, что я делаю неправильно, поскольку он все еще не удаляет пробелы (обрезает) поле имени.

Ответы [ 6 ]

21 голосов
/ 14 июня 2011

Когда вы используете экземпляр ModelForm для создания / редактирования модели, метод clean () модели гарантированно будет вызван.Итак, если вы хотите удалить пробелы из поля, вы просто добавляете метод clean () в вашу модель (не нужно редактировать класс ModelForm):

class Employee(models.Model):
    """(Workers, Staff, etc)"""
    name = models.CharField(blank=True, null=True, max_length=100)

    def clean(self):
        if self.name:
            self.name = self.name.strip()

Я считаю следующий фрагмент кода полезным:он обрезает пробелы для всех полей модели, которые подклассируют либо CharField, либо TextField (так что это также перехватывает поля URLField) без необходимости указывать поля по отдельности:

def clean(self):
    for field in self._meta.fields:
        if isinstance(field, (models.CharField, models.TextField)):
            value = getattr(self, field.name)
            if value:
                setattr(self, field.name, value.strip())

Кто-то правильно указал, что вам не следуетиспользуя null = True в объявлении имени.Рекомендуется избегать значения null = True для строковых полей, в этом случае приведенное выше упрощается до:

def clean(self):
    for field in self._meta.fields:
        if isinstance(field, (models.CharField, models.TextField)):
            setattr(self, field.name, getattr(self, field.name).strip())
11 голосов
/ 18 февраля 2011

Должна быть вызвана очистка модели (она не автоматическая), поэтому добавьте self.full_clean() в свой метод сохранения.
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.full_clean

Что касается вашей формы, вам необходимо вернуть очищенные очищенные данные.

return self.cleaned_data['name'].strip()

Почему-то я думаю, что вы просто пытались сделать кучу вещей, которые не работают. Помните, что формы и модели - это две совершенно разные вещи.

Проверьте документы форм на то, как проверять формы http://docs.djangoproject.com/en/dev/ref/forms/validation/

super(Employee), self.clean().strip() makes no sense at all!

Вот ваш исправленный код:

class Employee(models.Model):
    """(Workers, Staff, etc)"""
    name = models.CharField(blank=True, null=True, max_length=100)

    def save(self, *args, **kwargs):
        self.full_clean() # performs regular validation then clean()
        super(Employee, self).save(*args, **kwargs)


    def clean(self):
        """
        Custom validation (read docs)
        PS: why do you have null=True on charfield? 
        we could avoid the check for name
        """
        if self.name: 
            self.name = self.name.strip()


class EmployeeForm(ModelForm):
    class Meta:
        model = Employee


    def clean_name(self):
        """
        If somebody enters into this form ' hello ', 
        the extra whitespace will be stripped.
        """
        return self.cleaned_data.get('name', '').strip()
5 голосов
/ 24 января 2014

Если у вас так много полей данных, которые нужно обрезать, почему бы не попробовать расширить CharField?

from django.db import models
from django.utils.translation import ugettext_lazy as _

class TrimCharField(models.CharField):
   description = _(
       "CharField that ignores leading" 
       " and trailing spaces in data")

   def get_prep_value(self, value)
       return trim(super(TrimCharField, self
           ).get_prep_value(value))

   def pre_save(self, model_instance, add):
       return trim(super(TrimCharField, self
           ).pre_save(model_instance, add))

ОБНОВЛЕНИЕ: Для версий Django <= 1,7, если вы хотите расширить поле, вы должны использовать модели.SubfieldBase метакласс.Так что здесь это будет выглядеть так: </p>

class TrimCharField(six.with_metaclass(
    models.SubfieldBase, models.CharField)):
4 голосов
/ 12 июля 2016

Django 1.9 предлагает простой способ сделать это. Используя аргумент strip, значение по умолчанию - True, вы можете убедиться, что начальные и конечные пробелы урезаны. Вы можете сделать это только в полях формы, чтобы убедиться, что пользовательский ввод обрезан. Но это все равно не защитит саму модель. Если вы все еще хотите это сделать, вы можете использовать любой из методов, описанных выше.

Для получения дополнительной информации посетите https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield

3 голосов
/ 18 февраля 2011

Я рассматриваю это в качестве декоратора.Я также усекаю значения полей, которые превышают значение max_length CharField.

0 голосов
/ 16 января 2018

Если вы все еще не в Django 1.9+, позор вам (и мне) и добавьте это в форму. Это похоже на ответ @ jeremy-lewis, но у меня было несколько проблем с ним.

def clean_text_fields(self):
    # TODO: Django 1.9, use on the model strip=True
    # https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield
    from django.forms.fields import CharField
    cd = self.cleaned_data
    for field_name, field in self.fields.items():
        if isinstance(field, CharField):
            cd[field_name] = cd[field_name].strip()
            if self.fields[field_name].required and not cd[field_name]:
                self.add_error(field_name, "This is a required field.")

def clean(self):
    self.clean_text_fields()
...