[英](Django) Trim whitespaces from charField
如何從Django中的charField末尾刪除空格(trim)?
這是我的模型,你可以看到我已經嘗試過使用干凈的方法,但這些方法永遠不會運行。
我也嘗試過使用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()
編輯:更新了我最新版本的代碼。 我不確定我做錯了什么,因為它仍然沒有剝離空白(修剪)名稱字段。
當您使用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())
必須調用模型清理(它不是自動的),所以在save方法中放置一些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()
如果要修剪這么多數據字段,為什么不嘗試擴展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,如果你想擴展字段,你將使用models.SubfieldBase元類。 所以這里會是這樣的:
class TrimCharField(six.with_metaclass(
models.SubfieldBase, models.CharField)):
Django 1.9提供了一種簡單的方法來實現這一點。 通過使用默認為True的strip
參數,可以確保修剪前導和尾隨空格。 您只能在表單字段中執行此操作,以確保修剪用戶輸入。 但這仍然無法保護模型本身。 如果您仍想這樣做,可以使用上述任何方法。
有關更多信息,請訪問https://docs.djangoproject.com/en/1.9/ref/forms/fields/#charfield
我作為裝飾者在視圖中處理它。 我還截斷了超過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
如果你還沒有對你(和我)的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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.