Django request.POST作为表单的参数

Apa*_*ear 2 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})
Run Code Online (Sandbox Code Playgroud)

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

额外的问题,为什么form = ContactForm(request.POST)然后在else:块中重复。为什么有用,什么时候有用?例子?

pat*_*eet 6

简而言之,request.POST就是提交表单时发送的数据。它的用户提交的什么字典firstnamelastnameemail你的代码样本。对于那些来自PHP背景的人,这是提供的$_POST

form = ContactForm(request.POST)将数据绑定到form类,以便Django可以做一些有趣的事情,例如使用验证输入is_valid()

那为什么要添加request.POSTelse:块中呢?那么,您是否曾经向网站提交过表单,并且在出现错误时必须再次完全填写表单?那是糟糕的用户体验,对吧?通过将表单中的数据与用户一起发送回给用户request.POST,您可以重新呈现用户输入的内容-以及诸如错误消息之类的有用附加内容,以便他们可以对其进行修复并重新提交。

编辑:要展开,这是Django中BaseForm类init方法

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)
Run Code Online (Sandbox Code Playgroud)

当您传递request.POST到表单类时,您实际上就是在做data=request.POST。反过来触发self.is_bound = True