2011-02-18 16 views
14

¿Cómo elimino los espacios en blanco (recorte) del final de un charField en Django?(Django) Recorte los espacios en blanco de charField

Aquí está mi modelo, como puedes ver, he intentado poner en métodos limpios pero estos nunca se ejecutan.

También he intentado hacer name.strip(), models.charField().strip() pero estos tampoco funcionan.

¿Hay alguna manera de forzar el recorte de chasis para mí automáticamente?

Gracias.

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() 

Editado: código actualizado a mi última versión. No estoy seguro de lo que estoy haciendo mal, ya que todavía no está eliminando el espacio en blanco (recorte) del campo de nombre.

Respuesta

10

Se debe llamar a la limpieza del modelo (no es automática), por lo tanto, coloque algunos self.full_clean() en su método de guardar.
http://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.full_clean

En cuanto a su forma, debe devolver los datos depurados.

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

De alguna manera, creo que acabas de intentar hacer un montón de cosas que no funcionan. Recuerde que las formas y los modelos son 2 cosas muy diferentes.

comprobar en la documentación se forma sobre cómo validar formas http://docs.djangoproject.com/en/dev/ref/forms/validation/

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

Aquí está el código fijo:

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() 
+0

Todavía estoy teniendo problemas, todavía no se está eliminando el espacio en blanco (recorte). Intenté seguir el tutorial que publicaste y tu idea de llamar a full_clean() en el método de guardar. Estoy luchando por entender a) ¿Se llama al Formulario de Empleado? b) ¿Se está llamando al método full_clean()? He actualizado mi código de muestra en mi pregunta. Tengo la esperanza de poder apuntar en la dirección correcta. – zardon

+0

Déjeme copiar y pegar su código y modificarlo. –

+0

Gracias por su ayuda, soy bastante nuevo en Django/Python; así que me disculpo por los diversos errores y malentendidos sobre cómo debería implementar varias características. – zardon

3

estoy manejando esto en vistas como un decorador. También estoy truncando valores de campo que exceden un valor de CharField max_length.

from django import forms 
from django import models 
from django.db.models.fields import FieldDoesNotExist 
from django.utils.encoding import smart_str 

class CleanCharField(forms.CharField): 
     """Django's default form handling drives me nuts wrt trailing 
     spaces. http://code.djangoproject.com/attachment/ticket/6362 
     """ 
     def clean(self, value): 
      if value is None: 
       value = u'' 
      value = smart_str(value).strip() 
      value = super(forms.CharField, self).clean(value) 
      return value 

def truncate_charfield(model): 
    """decorator to truncate CharField data to model field max_length. 
    Apply to the clean method in views Form: 

    @truncate_charfield(MyModel) 
    def clean(self): 
     ... 
    """ 
    def wrap(f): 
     def wrapped_f(*args): 
      f(*args) 
      d = args[0].cleaned_data 
      for field in model._meta.fields: 
       try: 
        mf = model._meta.get_field(field.name) 
        if isinstance(mf, models.CharField) and field.name in d: 
         d[field.name] = d[field.name][:mf.max_length] 
       except FieldDoesNotExist: 
        pass 
      return d 
     return wrapped_f 
    return wrap 
+0

Gracias, pero parece demasiado avanzado para mí, no estoy seguro de dónde colocaría este archivo, cómo lo llamaría, etc .; pero cuando recojo Django/Python estoy seguro de que recogeré todo esto en el camino. Gracias de nuevo. – zardon

+0

zardon, simplemente podría ponerlo en un módulo, digamos maxtruncate.py luego importar a su views.py: from maxtruncate import CleanCharField, truncate_charfield. Luego reemplace CharField con CleanCharField y coloque el decorador truncate_charfield en la parte superior de su método de limpieza. La principal ventaja es que no tendrá su campo de entrada excediendo su max_length ... lo que causará un desagradable error en el tiempo de ejecución de su base de datos. –

19

Cuando está utilizando una instancia de ModelForm para crear/editar un modelo, se garantiza que se llamará al método clean() del modelo. Por lo tanto, si se quiere despojar a los espacios en blanco de un campo, que acaba de añadir un método limpio() para su modelo (sin necesidad de editar la clase 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() 

encuentro el siguiente fragmento de código útil- recorta el espacio en blanco para todos los campos del modelo que la subclase sea CharField o campo de texto (por lo que también atrapa campos campo URLy) sin necesidad de especificar los campos individualmente:

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()) 

Alguien señaló correctamente que no se debe utilizar nula = True en la declaración del nombre. La mejor práctica es evitar null = True para campos de cadena, en cuyo caso los anteriores simplifica a:

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()) 
+1

Buena solución. Sin embargo, la única cosa que cambiaría es: ** if value and hasattr (value, 'strip'): ** Como algunos campos personalizados no contienen un método de tira para un valor (al menos es mi caso)) Esto protege contra eso. –

5

Si tiene tantos campos de datos para ser recortadas, por qué no intentar extender 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)) 

UPDATE: Para las versiones de Django < = 1.7 si desea ampliar el campo, debe usar modelos. MetaclassSubfieldBase. Así que aquí será como:

class TrimCharField(six.with_metaclass(
    models.SubfieldBase, models.CharField)): 
3

Django 1.9 ofrece una manera simple de lograr esto. Al utilizar el argumento strip cuyo valor predeterminado es Verdadero, puede asegurarse de que los espacios en blanco inicial y final se recortan. Sin embargo, solo puedes hacer eso en los campos del formulario para asegurarte de que la entrada del usuario esté recortada. Pero eso aún no protegerá el modelo en sí. Si aún desea hacer eso, puede usar cualquiera de los métodos anteriores.

Para obtener más información, visite https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield

0

Si todavía no estás en Django 1.9+ la culpa es tuya (y yo) y colocar esto en su formulario. Esto es similar a la respuesta de @ jeremy-lewis, pero tuve varios problemas con la suya.

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() 
Cuestiones relacionadas