当前位置: 首页 > 知识库问答 >
问题:

Django:如何防止模型表单字段呈现但将其包含在验证中?

平庆
2023-03-14

假设我有以下模型:

class Folder(models.Model):
    name = models.CharField(default='untitled', max_length=255)
    parent = models.ForeignKey('self', null=True, blank=True)
    root = models.ForeignKey('self', null=True, blank=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

我用custom clean()创建了一个自定义ModelForm,它正在像一个魅力一样工作(根据unittests和手动测试):

class FolderForm(ModelForm):

    def __init__(self, *args, **kwargs):
        try:
            data = kwargs.get('data', None).copy()
        except AttributeError:
            data = None
        self.prefix = kwargs.get('prefix')
        user = kwargs.pop('user', None)

        if data is not None:
            if user is not None:
                data[self.add_prefix('user')] = user.id
            kwargs['data'] = data

        super(FolderForm, self).__init__(*args, **kwargs)

    def clean(self):
        # just working fine, so I won't include it here
        pass

    class Meta:
        model = Folder
        fields = '__all__'

所以,因为我的根文件夹只是一个普通的FKs为空的Folder-object,所以我甚至不想在创建时向用户显示这些字段。我为此创建了另一个表单:

class AddRootFolderForm(FolderForm):
    class Meta:
        model = Folder
        exclude = ['parent', 'root', 'user']

正如您所看到的,我也排除了用户,这个值将在视图中设置。当前,这是我的视图代码:

@login_required
def create_rootfolder(request):
    if request.method == 'POST':
        form = FolderForm(data = request.POST,
                          user = request.user)
    else:
        form = AddRootFolderForm()

    if form.is_valid():
        new = form.save()
        return redirect('show_rootfolder', root_id = new.id)

    return render(request, 'create_rootfolder.html',
                  { 'form': form })

这整个设置是有效的,但似乎是可怕的骇人听闻。有没有更好的方法来向用户隐藏某些字段(意思是:甚至不要将它们显示为隐藏字段),而是将它们包含在验证中?我的主要问题是,我不能使用相同的表单来显示和验证,因为如果我使用AddRootFolderForm作为单个表单实例,排除的字段将不会被验证。

我知道我可以在构造函数中动态地排除字段,我甚至尝试过这样做,但它使我的构造函数膨胀到50LOC,这似乎是不干净的。

那么,验证所有字段的模型的最佳方法是什么,即使这些字段没有包含在显示给用户的表单中?

共有1个答案

章建木
2023-03-14

为什么要验证表单中没有使用的字段?

清理过程是检查用户发布的数据的方法。模型操作所需的其余数据必须在表单验证之后添加

 if form.is_valid():
     new = form.save(commit=False)
     new.user = request.user
     ...
     new.save()
 类似资料:
  • 问题内容: 如果我有Django表单,例如: 我调用了这种形式的实例的as_table()方法,Django将按照上述指定的顺序渲染字段。 我的问题是Django如何知道类变量的定义顺序? (例如,当我想从类的init方法中添加字段时,如何覆盖此顺序?) 问题答案: 我继续回答了自己的问题。这是供将来参考的答案: 在中,使用该方法将类变量最终按类中定义的顺序加载到其中,这确实有些不可思议。 是实例

  • 问题内容: 我有这个模特 我希望用户在两个字段中都不能使用字母数字以外的任何其他字符。 有什么办法吗? 问题答案: 您将使用验证器来限制字段接受的内容。A可以在这里实现窍门: 请注意,已经有一个验证器可以为您验证电子邮件地址。上述验证器将不允许使用有效的电子邮件地址。

  • 本文向大家介绍Django实现表单验证,包括了Django实现表单验证的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Django实现表单验证的具体代码,供大家参考,具体内容如下 models.py form.py view.py register.html 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 假设我们有以下模型: 假设不是通过ManyRelatedPrimaryKeyField函数获得这样的结果: 让它返回包含完整相关模型表示的内容,例如: 这可能吗?如果是这样,怎么办?这是一个坏主意吗? 问题答案: 最简单的方法是使用depth参数 但是,这仅包括前向关系的关系,在这种情况下,这并不是你真正需要的,因为教师字段是反向关系。 如果你有更复杂的要求(例如,包括反向关系,嵌套一

  • 问题内容: 现在我有这行: 但是,由于程序属于公司,我想显示公司名称而不是公司ID。 渲染程序时如何包括公司名称? 问题答案: 这样的事情应该起作用:

  • 问题内容: 据我了解,当创建一个Django应用程序时,数据会先通过表单进行验证,然后再插入模型实例中,然后再写入数据库中。但是,如果我想在数据模型层上创建一个额外的保护层,那么在目前的“最佳实践”之下我做了什么?我试图确保审稿人的姓名不会被遗漏或保留为空白。我是否应该像在此所做的那样在“ clean”方法中放入任何自定义验证,然后让“ save”调用“ full_clean”(称为“ clean