Django:如何在基于类和基于函数的自定义验证器之间做出决定?

这是一个初学者的问题。

我最初是这样声明该字段的:


from django.db import models

from django.core.validators import FileExtensionValidator


def user_directory_path(instance, filename):

    """

    Code to return the path

    """


class Project(models.Model):

    """

    """

    # ...Some model fields...

    # Right now I'm only validating and testing with .mp4 files.

    video_file = models.FileField(

        upload_to=user_directory_path,

        validators=[FileExtensionValidator(allowed_extensions=['mp4'])]

    )

但我在几个地方读到,最好使用它libmagic来检查文件的幻数并确保其内容与扩展名和 MIME 类型匹配。我对此很陌生,所以我可能会弄错一些东西。

我按照验证器参考编写了一个使用magic. 该文档还讨论了“带有方法的类”,这里__cal__()获得最多支持的答案使用基于类的验证器。文档说这可以“对于更复杂或可配置的验证器”来完成,但我不明白具体的例子是什么,以及我的基于函数的验证器是否足以满足我想要做的事情。我想是的,但我没有经验来确定。

这就是我所拥有的。

models.py

from django.db import models

from .validators import validate_media_file


def user_directory_path(instance, filename):

    """

    Code to return the path

    """


class Project(models.Model):

    """

    """

    # ...Some model fields...

    # Right now I'm only validating and testing with .mp4 files.

    video_file = models.FileField(

        upload_to=user_directory_path,

        validators=[validate_media_file]

    )


迁移工作与此相关。我还使用扩展名为 .mp4 的纯文本文件进行了测试,然后使用不同的文件(和扩展名)对其进行了测试,并且它可以工作。但是,我想知道使用它而不是基于类的验证器是否会丢失一些东西,而且,正如标题所说,我应该何时使用它,因为我可能会遇到另一种情况,在这种情况下我会需要知道它。


我知道我没有包含 MIME 类型;我可以稍后再做。


magic.from_buffer()作为另一个问题,当输出与扩展名和/或 MIME 类型不匹配时,适当的错误消息是什么?我想到了“文件已损坏”的说法,但我不确定。实际上,这是直接基于幻数的输出吗?


米琪卡哇伊
浏览 64回答 1
1回答

慕尼黑5688855

何时使用基于类的验证器?在您的示例中,基于函数的验证器就足够了。如果您需要 OOP、类和对象的优点,那么您应该切换到基于类的验证器。想象一下以下非常虚构的源代码:class StartsWithValidator():    def __init__(self, starts_with):        self.starts_with = starts_with    def __call__(self, value):        if not str(value).startswith(self.starts_with):            raise ValidationError(                'Your string does not start with: {}!'.format(self.starts_with),                params={'value': value}            )my_validator = StartsWithValidator('123')test_string = '123OneTwoThree'my_validator(test_string) # Will it pass the validator?您可以在这里看到不同的品质:通过基于类的验证器,您可以使用对象。对象共享相同的功能但具有不同的内部状态。您现在可以设置一个验证器,它检查字符串是否以“abc”、“123”开头,而无需编写新代码starts_with_abc = StartsWithValidator('abc')starts_with_123 = StartsWithValidator('123')starts_with_whatever = StartsWithValidator('whatever')您可以使用继承。想象一下,您想要在其他功能中重用starts-with-validation,您只需从“StartsWithValidator”类继承即可。class StartsWithABCValidator(StartsWithValidator):    def __init__(self):        super().__init__('ABC')    def __call__(self, value):        super().__call__(value)如果你的验证器做了很多复杂的事情,一个简单的函数可能会导致可读性差的代码。如果您使用类,您就可以封装您的功能并将其分组在一起。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python