如何在 django 中正确验证用户是否年满 18 岁?

How can properly verify a user is 18 or older in django?

提问人:Grimidk 提问时间:11/15/2023 最后编辑:Grimidk 更新时间:11/15/2023 访问量:68

问:

我想验证用户的年龄 () 是否为 18+,这是我当前的代码,尽管它不起作用:birth_date

...
def min_date():
    return (date.today() - timedelta(days=6570))

class User(BaseModel, RemovabledModel, AbstractUser):
 birth_date = models.DateField(
        verbose_name=_('birth date'),
        help_text=_('Birth date'),
        null=True,
        blank=True,
        validators=[
            MinValueValidator(
                limit_value=min_date(),
                message=("User must be 18 or older")
            ),
        ]
    )

它运行并正常运行,但我仍然可以将用户的年龄设置为今天的日期,而不会像其他验证器那样应用程序抛出任何错误消息。

编辑:如果它是相关的,这是相关的验证器:

def min_date(): 
    return (date.today() - timedelta(days=6570)) 

class SignUpSerializer(serializers.Serializer): 
    birth_date = serializers.DateField( 
        write_only=True, 
        required=True, 
        validators=[ 
            MinValueValidator( 
                limit_value=min_date(), 
                message=("User must be 18 or older") ),
        ] 
    )
python django django-models django-validation

评论

0赞 willeM_ Van Onsem 11/15/2023
如何验证用户输入?你能显示视图/模板/...你用来让用户输入数据,以及它是如何处理的?
0赞 Grimidk 11/15/2023
@willeM_VanOnsem,用户可以使用序列化的 API 进行注册,但我目前正在从 Django 管理仪表板对其进行测试。序列化程序本身确实具有相同的验证程序。
0赞 willeM_ Van Onsem 11/15/2023
你能分享序列化程序吗?
0赞 Grimidk 11/15/2023
@willeM_VanOnsem, ''' def min_date(): return (date.today() - timedelta(days=6570)) class SignUpSerializer(serializers.序列化程序):birth_date = 序列化程序。DateField( write_only=True, required=True, validators=[ MinValueValidator( limit_value=min_date(), message=(“用户必须年满 18 岁”) ), ] ) '''
0赞 willeM_ Van Onsem 11/15/2023
编辑问题,以及您正在使用的(视图)集和 POST 请求?

答:

0赞 nigel239 11/15/2023 #1

您可以像这样修复模型上的验证(这也意味着您可以从序列化程序中省略自定义字段):

def min_date():
    return (date.today() - timedelta(days=6570))

class User(BaseModel, RemovabledModel, AbstractUser):
 birth_date = models.DateField(
        verbose_name=_('birth date'),
        help_text=_('Birth date'),
        null=True,
        blank=True,
    )
    def clean(self):
        super().clean()
        if self.birth_date > min_date():
             # raise validation error here             

相关文档
自定义用户模型

它目前在模型上的设置方式:

在用户模型中的日期字段上;您正在验证器中调用 min_date() 函数,假设您要迁移。
你开始了一天的工作。
然后第二天;你回到开发;你进行迁移,迁移;它应该说没有进行任何更改,但日期字段发生了变化
min_date函数中的日期将递增。

在这种情况下,迁移不知道您正在调用函数;它只是看到了价值。

评论

1赞 John Gordon 11/15/2023
使用特定的清洁方法而不是使用通用方法不是更好吗?clean_birth_dateclean
0赞 nigel239 11/15/2023
@JohnGordon 是的,会的。去向 django 开发人员抱怨,因为这不是模型上的功能;而是在表格上。:)(对不起,如果这听起来很粗鲁,我不是故意的。docs.djangoproject.com/en/4.2/ref/models/instances/......
1赞 John Gordon 11/15/2023
啊,我明白了。我应该意识到这是模型验证与表单验证。