Django - 检查模型字段格式

0 投票
2 回答
781 浏览
提问于 2025-04-17 17:04


我在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

根据需要使用 sself

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

你的 validmodify 函数可能都应该换成一个叫 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。这种方式被称为“宁可请求原谅,也不要请求许可”的原则(它还可以防止一些竞争条件 - 不过在这个情况下可能不太相关)。

撰写回答