Django request.POST作为表单的参数

时间:2014-03-20 05:38:41

标签: django django-forms

我很难绕过什么请求.POST在以下示例中作为参数进行:

def addauthorView(request):
if request.method == 'POST':
     form = ContactForm(request.POST)
     if form.is_valid():
        first_name = form.cleaned_data['firstname']
        last_name = form.cleaned_data['lastname']
        user_email = form.cleaned_data['email']
        c = AuthorModel(firstname=first_name, lastname=last_name, email=user_email)
        c.save()
        return HttpResponseRedirect('thanks/')
     else:
        form = ContactForm(request.POST)
        return render(request, 'addauthor.html', {'form': form})

所以我知道这有效,但出于某种原因,我无法理解form = ContactForm(request.POST)所发生的魔力。为什么ContactForm需要request.POST参数?幕后发生了什么?

额外的问题,为什么form = ContactForm(request.POST)会在else:块重复出现。为什么这有用,什么时候有用?实例

1 个答案:

答案 0 :(得分:4)

简而言之,表单提交时,request.POST只是the data that was sent。它是您在代码示例中为firstnamelastnameemail提交的内容的字典。对于那些来自PHP背景的人来说,它是$_POST中提供的内容。

form = ContactForm(request.POST)将数据绑定到表单类,因此Django可以使用is_valid()来验证输入等有趣的内容。

为什么然后,您会将request.POST添加到else:块?那么,你有没有向网站提交过表格,当出现错误时你必须再次填写表格?这是一个糟糕的用户体验,对吗?通过使用request.POST中的数据将表单发回给用户,您可以重新呈现用户输入的内容 - 以及错误消息等有用的附加内容 - 以便他们可以修复并重新提交。

编辑:要展开,这是init method from the BaseForm class in Django

def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
             initial=None, error_class=ErrorList, label_suffix=None,
             empty_permitted=False):
    self.is_bound = data is not None or files is not None
    self.data = data or {}
    self.files = files or {}
    self.auto_id = auto_id
    self.prefix = prefix
    self.initial = initial or {}
    self.error_class = error_class
    # Translators: This is the default suffix added to form field labels
    self.label_suffix = label_suffix if label_suffix is not None else _(':')
    self.empty_permitted = empty_permitted
    self._errors = None  # Stores the errors after clean() has been called.
    self._changed_data = None

    # The base_fields class attribute is the *class-wide* definition of
    # fields. Because a particular *instance* of the class might want to
    # alter self.fields, we create self.fields here by copying base_fields.
    # Instances should always modify self.fields; they should not modify
    # self.base_fields.
    self.fields = copy.deepcopy(self.base_fields)

当您将request.POST传递到表单类时,您确实正在data=request.POST。这又会触发self.is_bound = True