【问题标题】:Django ModelForm: How to perform an expensive field validation only rarely?Django ModelForm:如何很少执行昂贵的字段验证?
【发布时间】:2016-04-05 18:50:41
【问题描述】:

我有一个包含十几个字段的模型。 它的实例是通过一个包含十几个字段的表单创建的。 其中一个字段是我需要检查其实际可访问性的 URL。 该检查需要登录并且需要相当长的时间(大约 4 秒), 所以我想尽可能少地执行它——但也 早在用户期望的时候,即在输入 URL 之后。

简而言之,我想在表单验证时验证 URL, 除非我之前验证了相同的 URL(在 以前的请求)。

我想知道把这个逻辑放在哪里。 我的代码使用vanilla.CreationView 基于类的视图。

from django.db import models
import vanilla

class MyModel(models.model):
    url = models.URLField()  # a very remote URL
    # and many others

class CreateView(vanilla.CreateView):
    model = MyModel
    template_name = "create.html"

我首先尝试直接在模型中进行检查, 以某种方式使用has_changed()

我花了很长时间才意识到这 无法工作(我还是 Django 新手): 表单无法知道随 previous POST 请求,因为没有合适的状态 可用:

  • 模型实例还不存在(这是创建视图!)。
  • 该模型即使在UpdateView 中也无济于事, 因为用户可能会多次更改该值 在两个 save() 调用之间,而表单没有 验证。

似乎有两种可能:

  • 将持久状态存储在单独的ValidationStatus 模型中。 这听起来很麻烦,而且是一种可怕的矫枉过正。
  • 让浏览器通过某种方式发回之前的值 的一个隐藏字段。 对我来说听起来更明智。

两个问题:

  • 以上考虑是否正确?
  • 添加这样一个隐藏字段的代码最少的方法是什么 到实际表单并管理验证工作流程? 我想维护提供的可爱的自动化支持 尽可能使用 Django 和 vanilla 视图。

【问题讨论】:

  • 我会在会话中存储一个有效 url 的字典。
  • 另一种选择是使用标准 Django 缓存 API 将其存储在缓存中。

标签: django validation django-models django-forms


【解决方案1】:

缓存!

koniiiik 的评论是正确的:这是caching 的完美用例,因为在我的情况下,该 URL 的可访问性 是全局属性; 它不依赖于用户,因此不依赖于会话, 并且与该特定形式或模型实例无关。

我现在已经实现了一个简单的validator function 附加到 url 模型字段是这样的:

    def validate_url_accessibility(url):
        cache_key = "%s is accessible" % url
        if django.core.cache.cache.get(cache_key):
            return  # alright: access has been validated before
        if not accessible(url):
            raise ValidationException("...")
        django.core.cache.cache.set(cache_key, True)

像魅力一样工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-07
    • 2018-03-27
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2012-09-30
    • 1970-01-01
    相关资源
    最近更新 更多