我在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.
我正在编写有效的函数,我想执行评论中详述的命令 对于(1),我使用
if k not in s.__dict__: return False
我需要一些帮助(2)
也就是说,如何检查某个值是否符合为属性定义的格式(Django模型字段)?
例如:valid(s_name = True)和valid(s_name = 33 *'a')都应返回False。
注意:我正在尝试在不使用Forms的情况下解决此验证问题。
答案 0 :(得分:1)
您的valid
和modify
函数都应该替换为clean
方法。
更新1
您可以完全放弃有效方法,只需拨打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模式,如果有效/那么。它被称为“更好地请求宽恕而不是许可”原则(除其他外,它提供了对抗竞争条件的保护 - 在这种情况下可能不相关)
答案 1 :(得分: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])