Django 1.6 最佳实践: Django Forms 的其他使用技巧

在我们的博客中, 记录了我们在开发过程中所使用的技术和遇到的问题, 希望作为其他开发和设计者的一个学习交流平台.

Django 1.6 最佳实践: Django Forms 的其他使用技巧


Django forms确实强大, 但在使用过程中, 你也许会觉得有些地方使用起来很困惑. 不过, 如果你了解forms的结构的, 那么这些困惑就能立刻变得清晰:

1. 何时使用POST方法

如果HTML form中提交的是需要修改数据内容的动作, 那么就应当使用POST, 唯一的例外是search form, 因为提交的搜索并不会修改数据:

    <form action="/article/add/" method="POST">

还有需要注意的是, 不要关闭django 的CSRF保护, 详细可以查看https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/

2. Django Forms的验证过程

上一篇中, 我们介绍了怎么自定义forms的验证. 进一步理解Forms验证的过程, 可能会帮助你编写更好的代码. 接下来让我们看一下forms的验证过程. 当执行form.is_valid()时, 以下步骤会一步接着一步发生:

  • 1.如果form已捆绑数据(bound data), 那么form.is_valid()会调用form.full_clean()方法:
  • 2.form.full_clean()将依次验证每个field:
    • a.通过to_python()方法将field中数据转化为对应python数据类型
    • b.针对不同field类型, 进行field类型验证和自定义validator验证
    • c.通过自定义的clean<field>()方法验证
  • 3.执行form.clean()方法
  • 4.如果是ModelForm, 则调用form.post_clean()方法:
    • a.无论form.is_valid()返回是True或False, 将form的数据传到对应的model实例中
    • b.调用model的clean()方法 (使用ORM保存model时, 并不会调用model的clean()方法)

我们可以看出, form的数据先保存到from实例中, 如果是ModelForm, 则再保存到model实例中. 因为在没有使用form.save()之前, model实例是不会被写入数据库的. 这样, 我们就有机会记录并保存用户的错误输入:

    # utils/models.py
    from django.db import models
    
    class FailureHistory(models.Model):
        form_data = models.TextField()
        model_data = models.TextField()
    # myapp/models.py
    import json
    
    from django.core import serializers
    from django.views.generic import CreateView
    
    from utils.models import FailureHistory
    
    class ArticleCreateView(CreateView):
        ...
        
        def form_invalid(self, form):
            form_data = json.dumps(form.cleaned_data)
            model_data = serializers.serialize("json", [form.instance])[1:-1]
            FailureHistory.objects.create(
                form_data = form_data,
                model_data = model_data
            )
            return super(ArticleCreateView, self).form_invalid(form)

原文链接: http://weiguda.com/blog/13/