在 Django 中手动设置 clean_data 有什么危险吗?

sha*_*fin 3 django django-forms

这可能是一个愚蠢的问题,但我有点不确定手动设置 clean_data 是否安全。文档

一旦 is_valid() 返回 True,您就可以安全地处理表单提交,因为您知道它符合表单定义的验证规则。虽然此时您可以直接访问 request.POST,但最好访问 form.cleaned_data。该数据不仅经过验证,还将为您转换为相关的 Python 类型。

为了获得更多上下文,假设我们有一个模型表单,其中包含多个字段,例如书名、书的作者和要求 url 的字段。

表单条件是:如果url字段为空,则用户必须提供标题和作者。如果给出了 url 字段而没有其他任何内容,我将从给定的 url 解析 html 并自动为用户提取标题和作者。

在我自动从 url 中获取标题和作者的情况下,处理将此数据保存到模型的最佳方法是什么,因为表单将为作者和标题返回一个空的 clean_data ?我确保解析的数据符合模型中的验证规则,但像这样设置 clean_data 似乎很可疑。

在模型类中:

def save(self, commit = True, *args, **kwargs):
    parsed_title = ... # String returned by my html parsing function
    parsed_author = ... # String returned by my html parsing function
    self.cleaned_data['title'] = parsed_title
    self.cleaned_data['author'] = parsed_author
Run Code Online (Sandbox Code Playgroud)

编辑:

谢谢,我是这样做的:

def save(self, commit=True, *args, **kwargs):
     instance = super(BookInfoForm, self).save(commit=commit, *args, **kwargs)
     ....
     instance.title = parsed_title
     instance.author = parsed_author

     return instance
Run Code Online (Sandbox Code Playgroud)

这有点偏离主题,因为您已经回答了原来的问题,但上面的代码破坏了其他部分。它不会将编译后的信息保存到 图书 IDhttp://..../media/books/<id>所在的位置,而是将其保存到.<id>http://..../media/books/None

我有一个添加/编辑功能来views.py处理添加和编辑:

def insert_or_modify(request, id=None):
    if id is not None:
         book = BookModel.objects.get(pk=id)
    else:
         book = BookModel()

   if request.method == 'POST':
       form = BookInfoForm(request.POST, instance=book)
       if form.is_valid():
           form.save()

   ....
   
   return render_to_response(...)
Run Code Online (Sandbox Code Playgroud)

有没有办法确保 id 存在,这样我就不会得到 id=None ?我想更具体地说,在模型表单中的 save() 中,是否有一种方法可以在 instance.id = None 的情况下创建带有 id 的新实例?尽管我认为调用 super(ModelForm, self).save(...) 会对我有用吗?

再次感谢!

Fac*_*ano 6

在您提出的情况下,您的意图不是设置 clean_data,而是设置模型数据。因此,不用在save方法中设置cleaned_data,只需设置其属性self.instance,然后保存即可。

关于手动设置cleaned_data,我认为这不一定是错误的,在表单的clean方法中进行一些跨字段验证可能是有意义的,尽管这不是常见情况。