You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django登录页Remember Me未勾选触发MultiValueDictKeyError问题解决

问题:登录页面Remember Me未勾选时触发MultiValueDictKeyError

尝试为登录页面添加Remember Me选项,勾选该选项时登录流程正常,但未勾选时会触发MultiValueDictKeyError: 'remember'错误。

相关代码

forms.py

class Signin(forms.Form):
    username = forms.CharField(
        max_length=9,
        widget=forms.TextInput(
            attrs={
                "id": "input_64",
                "name": "q64_typeA",
                "data-type": "input-textbox",
                "class": "form-textbox validate[required]",
                "data-defaultvalue": "",
                "size": "20",
                "placeholder": "180591001",
                "data-component": "textbox",
                "aria-labelledby": "label_64",
                "required": "",
            }
        ),
    )
    password = forms.CharField(
        max_length=255,
        widget=forms.PasswordInput(
            attrs={
                "id": "first_66",
                "name": "q66_name66[first]",
                "class": "form-textbox validate[required]",
                "data-defaultvalue": "",
                "autoComplete": "section-input_66 given-name",
                "size": "10",
                "data-component": "first",
                "aria-labelledby": "label_66 sublabel_66_first",
                "required": "",
                "placeholder": "•••••••••••••••",
            }
        ),
    )
    remember = forms.BooleanField(required=False, initial=False)

views.py

def signin(request):
    if request.user.is_authenticated:
        return redirect(index)
    if request.method == "POST":
        form = Signin(request.POST)
        if form.is_valid():
            username = request.POST["username"]
            password = request.POST["password"]
            remember = request.POST["remember"]

            user = User.objects.filter(username=username).exists()
            if user:
                get_user = User.objects.filter(username=username)
                check_pass = check_password(password, get_user[0].password)
                if not check_pass:
                    messages.error(request, "incorrect password")
                    return redirect(signin)
                else:
                    login(request, get_user[0])
                    if not remember:
                        request.session.set_expiry(0)
                    return redirect(index)
            else:
                messages.error(request, "Invalid User")
                return redirect(signin)
    else:
        form = Signin()
        return render(request, "accounts/login.html", {"form": form})

模板代码

<form class="jotform-form" action="/signin/" method="post" enctype="multipart/form-data" name="form_230023299150548" id="230023299150548" accept-charset="utf-8" autocomplete="on">
  {% csrf_token %}
  
  <div role="main" class="form-all">
    <ul class="form-section page-section">
      <li id="cid_60" class="form-input-wide" data-type="control_head">
        <div class="form-header-group  header-small">
          <div class="header-text httal htvam">
            <h3 id="header_60" class="form-header" data-component="header">SignIn</h3>
          </div>
        </div>
      </li>

      <li class="form-line jf-required" data-type="control_textbox" id="id_64">
        <label class="form-label form-label-left" id="label_64" for="input_64"> Username
          <span class="form-required">*</span>
        </label>
        <div id="cid_64" class="form-input jf-required">
          {{form.username}}
        </div>
      </li>

      <li class="form-line jf-required" data-type="control_fullname" id="id_66">
        <label class="form-label form-label-left form-label-auto" id="label_66" for="first_66">Password
          <span class="form-required">*</span>
        </label>
        <div id="cid_66" class="form-input jf-required">
          <div data-wrapper-react="true">
            <span class="form-sub-label-container" style="vertical-align:top" data-input-type="first">
              {{form.password}}
            </span>
        </div>
      </li>

      <li class="form-line jf-required" data-type="control_fullname" id="id_90">
        <label class="form-label form-label-left form-label-auto" id="label_90" for="first_90">Remember Me
        </label>
        <div id="cid_90" class="form-input jf-required">
          <div data-wrapper-react="true">
            <span class="form-sub-label-container" style="vertical-align:top" data-input-type="first">
              {{form.remember}}
            </span>
        </div>
      </li>
     
      <li class="form-line" data-type="control_button" id="id_76">
        <div id="cid_76" class="form-input-wide">
          <div data-align="center" class="form-buttons-wrapper form-buttons-center   jsTest-button-wrapperField"><button id="input_76" type="submit" class="form-submit-button submit-button jf-form-buttons jsTest-submitField" data-component="button" data-content="">Submit</button></div>
        </div>
      </li>
    </ul>
</form>

错误信息

MultiValueDictKeyError at /signin/
'remember'
Request Method: POST
Request URL:    http://localhost:8002/signin/
Django Version: 4.1.2
Exception Type: MultiValueDictKeyError
Exception Value:    
'remember'
Exception Location: /home/dubsy/virtualenvs/djangoproject/lib/python3.9/site-packages/django/utils/datastructures.py, line 86, in __getitem__
Raised during:  accounts.views.signin
Python Executable:  /home/dubsy/virtualenvs/djangoproject/bin/python
Python Version: 3.9.12

修复方案

核心原因

HTML表单中,未勾选的复选框不会被提交到后端,直接通过request.POST['remember']取值会触发键不存在的错误。

方案1:使用request.POST.get()安全取值

修改views.py中获取remember的代码,用get()方法指定默认值:

remember = request.POST.get('remember', False)

该方法会在键不存在时返回默认值False,避免报错。

方案2:使用表单cleaned_data(推荐)

既然已经使用Django表单,直接从验证后的表单数据中取值更规范,表单会自动处理布尔字段的默认值:

def signin(request):
    if request.user.is_authenticated:
        return redirect(index)
    if request.method == "POST":
        form = Signin(request.POST)
        if form.is_valid():
            # 从表单cleaned_data中获取验证后的值
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            remember = form.cleaned_data['remember']

            # 优化查询:用first()替代filter()[0],避免索引错误
            user = User.objects.filter(username=username).first()
            if user:
                check_pass = check_password(password, user.password)
                if not check_pass:
                    messages.error(request, "incorrect password")
                    return redirect(signin)
                else:
                    login(request, user)
                    if not remember:
                        request.session.set_expiry(0)
                    return redirect(index)
            else:
                messages.error(request, "Invalid User")
                return redirect(signin)
    else:
        form = Signin()
        return render(request, "accounts/login.html", {"form": form})

额外优化

  • 模板中Remember Me对应的li标签去掉jf-required类,因为该选项是非必填的:
<li class="form-line" data-type="control_fullname" id="id_90">

内容的提问来源于stack exchange,提问作者Olasubomi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:35:21