首页 > 解决方案 > 如何在不使用 ModelForm 的情况下为表单重用单个模型字段验证器?

问题描述

创建表单时如何重用模型字段验证器。我不能使用 ModelForm,因为表单只使用了模型的部分字段,而且我还有其他表单字段。

最小的例子

我有一个长度始终为 32 个字符的(加密)密钥模型,我想在模型和接受该密钥的表单中使用此限制。

模型.py

class EncryptionKey(models.Model)
    key = models.CharField("Encryption Key", max_length=32, validators=[validators.MinLengthValidator(32)])

表格.py

class NewUserForm(forms.Form):
    first_name = forms.CharField(label='First Name', required=True, max_length=256)
    last_name = forms.CharField(label='Last Name', required=True, max_length=256)
    key = # How do I reuse the key from the model here?

我正在寻找一种在 Django 2.1 中执行此操作的惯用方法。

我为此花了 20 分钟以上的时间在谷歌上搜索,但我发现的只是如何使用 ModelForm。

标签: djangopython-3.x

解决方案


我想我在Django docs for Models中找到了“规范”的答案(强调我的):

抽象基类

当您想将一些公共信息放入许多其他模型中时,抽象基类很有用。您编写基类并放入abstract=TrueMeta 类。该模型将不会用于创建任何数据库表。相反,当它用作其他模型的基类时,它的字段将添加到子类的字段中。

一个例子:

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)

Student 模型将具有三个字段nameagehome_group。该CommonInfo模型不能用作普通的 Django 模型,因为它是一个抽象基类。它不生成数据库表,也没有管理器,不能直接实例化或保存。

从抽象基类继承的字段可以用另一个字段或值覆盖,或者用None.

对于许多用途,这种类型的模型继承将正是您 想要的。它提供了一种在 Python 级别分解常见信息的方法,同时仍然在数据库级别为每个子模型创建一个数据库表。

我可以看到的唯一缺点是继承用于“has-a”关系而不是“is-a”。按照上面的例子:学生被建模为公共信息的专业化,但显然不是。


推荐阅读