フォームを用いたデータ登録時のエラー「MultiValueDictKeyError」

240 views
Skip to first unread message

sinf...@gmail.com

unread,
Feb 8, 2018, 9:01:39 AM2/8/18
to django-ja
当方Django初心者で以下のエラーで悩んでおります。

Formを用いたデータ登録処理にて「MultiValueDictKeyError」エラーが発生して
登録処理ができない状態です。

<データ登録画面の概要>
/form_test2にアクセスすると以下のような登録画面が表示されるので、
情報を入力してSaveボタンを押すと上記エラーが発生する。

------------------------------------------------------------
Envirnment: PROD,TEST,DEVの3つから選択
ServerName: 任意の文字列を入力
OS_version : リストから値を選択
CPU: 数値を入力
MEMORY:数値を入力
------------------------------------------------------------


エラーが発生している部分がviews.py内の以下の箇所です。

serverinfo.environment_id = request.GET["environment"]

envrinmentはモデルで定義されているクラスServerInfo内の項目ですが、
Envrinemtクラスを参照するForeignKeyになっています。

ServerInfoクラスのテーブルデータ内容
id          os_version  cpu         memory      environment_id  server_name
----------  ----------  ----------  --------- -  --------------  -----------
2           2012NR      21          129                1              server01
3           2012NR       5              5                 2               server02

Environmentクラスのテーブルデータ内容
id          env_value
----------  ----------
1           PROD
2           TEST
3           DEV

以下、URL,フォーム、ビュー、モデル等関連する部分の情報になります。
====================================================================
                     models.py
====================================================================
class Environment(models.Model):
    class Meta:
        verbose_name = '環境種別'
        verbose_name_plural = '環境種別'

    env_value = models.CharField(max_length=20)

    def __str__(self):
        return self.env_value

class ServerInfo(models.Model):

    class Meta:
        verbose_name = 'サーバ情報'
        verbose_name_plural = 'サーバ管理情報'

    OS_VERSIONS = (
        ('2012NR', 'WindowsServer2012'),
        ('2012SR2', 'WindowsServer2012R2'),
        ('2016NR', 'WinodwsServer2016NR'),
        )

    environment = models.ForeignKey(Environment, on_delete=models.CASCADE)
    server_name = models.CharField(max_length=50, unique=True)
    os_version = models.CharField(max_length=50,choices=OS_VERSIONS)
    cpu = models.IntegerField(default=1, help_text="単位はGB")
    memory = models.IntegerField(default=1, help_text="単位はGB")
    #@classmethod
    def __str__(self):
        return self.server_name
===============================================================


======================================================================
                              views.py
===============================================================
def form_test2(request):
    if request.method == "POST":
        form = ServerInfoForm(request.POST)
        if form.is_valid():
            serverinfo = form.save(commit=False)
            serverinfo.environment_id = request.GET["environment"]  →ここでエラーになっているっぽい。
            serverinfo.server_name = request.GET["server_name"]
            serverinfo.os_version = request.GET["os_version"]
            serverinfo.cpu = request.GET["cpu"]
            serverinfo.memory = request.GET["memory"]
            serverinfo.save()
            return redirect(detail, pk=serverinfo.pk)
    else:
        form = ServerInfoForm()
    return render(request, 'form_test.html', {'form': form})
======================================================================
======================================================================
                                urls.py
======================================================================
<関係する部分のみ抜粋>
url(r'^form_test2$', views.form_test2,name='form_test2'),
======================================================================


======================================================================
                                Form.py
======================================================================
from django import forms
from .models import ServerInfo

class ServerInfoForm(forms.ModelForm):
    class Meta:
        model = ServerInfo
        fields =("environment","server_name","os_version","cpu","memory")

======================================================================

======================================================================
                                form_test.html
======================================================================

{% extends 'base.html' %}

{% block content %}
   <H1>FORM画面テスト</H1>

   <form method="POST" class="post-form">{% csrf_token %}
          {{ form.as_p }}
          <button type="submit" class="save btn btn-default">Save</button>
     </form>
{% endblock content %}


おそらく、テンプレートに入力されたEnvirnmentの値(PROD,TEST,DEV)を受け取ってデータベースに
登録するときに正しい情報を渡せていないからだと思いますが、具体的にどのように修正すればエラーが
改善するのかいまいちわかりません。

以上、ご教授よろしくお願いいたします。

Shimizu N.

unread,
Feb 8, 2018, 8:29:07 PM2/8/18
to django-ja
清水と申します。
実際に再現したわけではありませんが、ぱっと見でviews.pyのこの部分。


> def form_test2(request):
>    if request.method == "POST":
>        form = ServerInfoForm(request.POST)
>        if form.is_valid():
>            serverinfo = form.save(commit=False)
>            serverinfo.environment_id = request.GET["environment"]  →ここでエラーになっているっぽい。
>            serverinfo.server_name = request.GET["server_name"]
> ...

POST処理なのでここは「request.GET["environment"]」ではなく「request.POST["environment"]」でOKなような気がしますがいかがでしょう?
 
2018年2月8日木曜日 23時01分39秒 UTC+9 sinf...@gmail.com:

sinf...@gmail.com

unread,
Feb 9, 2018, 7:13:08 AM2/9/18
to django-ja
清水さん

お世話になります。原です。

ご指摘ありがとうございます。
確かにおっしゃる通り・・・POST処理なのでrequest.GET[]は間違いでしたね・・・・
すべてrequest.POST["****"]に変更するとこで問題なくデータ登録できるようになりました。
ありがとうございました!


2018年2月9日金曜日 10時29分07秒 UTC+9 Shimizu N.:
Reply all
Reply to author
Forward
0 new messages