Django - 检查模型字段格式
我在Django里定义了一个简单的模型:
class Student(models.Model):
s_name = models.CharField(max_length=32)
s_gpa = models.FloatField(min=0.0, max=5.0, default=5.0)
s_year = models.IntegerField(min=1, max=10, default=1)
s_registered = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.username
def modify(self, **kwargs):
if valid(self, kwargs):
for k,v in kwargs.iteritems():
setattr(self, k, v)
self.save()
def valid(s, kwargs):
# For all k,v pairs in kwargs
# (1) Checks if k is one of the attributes of s. Returns False if fails.
# (2) Checks if v fits the format defined for attribute k of s.
# Returns False if fails.
# Returns True if reaches this point.
我正在写一个叫valid的函数,想要执行注释中详细说明的命令。
对于(1),我使用了
if k not in s.__dict__: return False
我需要一些帮助来解决(2)。
也就是说,我该如何检查一个值是否符合某个属性(Django模型字段)定义的格式呢?
举个例子:valid(s_name=True)和valid(s_name=33*'a')这两个调用都应该返回False。
注意:我想在不使用表单的情况下解决这个验证问题。
2 个回答
0
根据需要使用 s
或 self
。
def valid(self, kwargs):
for k, v in kwargs:
old_v = self.__dict__[k]
self.__dict__[k] = v
try:
self.save()
self.__dict__[k] = old_v
self.save()
except:
return False
return True
其实你可以用更直接的方法来测试,而不是依赖于真正的 'self.save()' 失败,不过从这里开始也是个不错的选择。
另外:
field_list = ['s_name', 's_gpa', 's_year', 's_registered']
def valid(self, kwargs):
for k, v in kwargs:
exclude_list = [f for f in field_list if f != k]
try:
self.clean_fields(exclude=exclude_list)
except ValidationError:
return False
return True
使用列表推导式,可以去掉 exclude_list
这一行,并把 self.clean_fields
这一行改成:
self.clean_fields(exclude=[f for f in field_list if f != k])
1
你的 valid
和 modify
函数可能都应该换成一个叫 clean
的方法。
可以看看关于 模型验证 的文档。
更新 1
你可以完全去掉 valid
方法,直接调用 self.clean_feilds()
。这样就会对字段进行验证。
def modify(self, **kwargs):
try:
self.clean_fields()
for k,v in kwargs.iteritems():
setattr(self, k, v)
self.save()
except:
pass
更新 2
从你的评论来看,你其实根本不需要自己去调用任何验证。只要调用 save
方法,如果你的修改不合法,就会抛出一个 ValidationError
的错误。
def modify(self, **kwargs):
try:
for k,v in kwargs.iteritems():
setattr(self, k, v)
self.save()
except ValidationError:
#... do something?
值得一提的是,很多 Python 程序员更喜欢使用 try / except 的方式,而不是 if valid / then。这种方式被称为“宁可请求原谅,也不要请求许可”的原则(它还可以防止一些竞争条件 - 不过在这个情况下可能不太相关)。