亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Django:如何在基于類和基于函數的自定義驗證器之間做出決定?

Django:如何在基于類和基于函數的自定義驗證器之間做出決定?

米琪卡哇伊 2023-10-31 21:46:11
這是一個初學者的問題。我最初是這樣聲明該字段的:from django.db import modelsfrom django.core.validators import FileExtensionValidatordef 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.pyfrom django.db import modelsfrom .validators import validate_media_filedef 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 類型不匹配時,適當的錯誤消息是什么?我想到了“文件已損壞”的說法,但我不確定。實際上,這是直接基于幻數的輸出嗎?
查看完整描述

1 回答

?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

何時使用基于類的驗證器?

在您的示例中,基于函數的驗證器就足夠了。如果您需要 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)

如果你的驗證器做了很多復雜的事情,一個簡單的函數可能會導致可讀性差的代碼。如果您使用類,您就可以封裝您的功能并將其分組在一起。


查看完整回答
反對 回復 2023-10-31
  • 1 回答
  • 0 關注
  • 148 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號