0


我在 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 的情况下解决此验证问题。

4

2 回答 2

1

你的validmodify函数都应该用一个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 模式而不是 if valid / then。它被称为“请求宽恕而不是许可”原则(除其他外,它提供了对竞争条件的保护——在这种情况下可能不相关)

于 2013-02-25T18:04:33.450 回答
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])
于 2013-02-25T18:05:17.303 回答