質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Q&A

解決済

2回答

1877閲覧

modelの更新がうまくできない

setuna0531

総合スコア128

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

0グッド

0クリップ

投稿2021/01/06 06:11

編集2021/01/07 06:25

#やっていること
現在、在庫管理アプリを個人的に作成しています。

#問題
primarykeyを設定しているコード以外のものをAdminサイトより更新することは出来ますが、
アプリより更新すると、PrimaryKeyと同じ値が既に存在しますと言われてしまいます。

Forms.pyにてPrimaryKeyの編集が出来ないよう、”readonly”の設定をしているため触れないのですが、
なぜか追加?という形で更新がかかってしまっているようです。

Primarykeyを外してみると普通に更新は行えており、更新したデータが2重で登録されるなどの事象はおきていません。
※PrimaryKeyを設定しているのはkamoku_codeです

#ソース

views

1from django.core.files.base import endswith_cr 2from django.http.response import Http404, HttpResponse 3from django.shortcuts import redirect, render, get_object_or_404 4from django.http import HttpResponse 5from .forms import KamokuForm, Kamoku_editForm 6from .models import Kamoku 7 8# Create your views here. 9 10def main(request): 11 return render(request, 'main.html') 12 13 14def kamoku(request): 15 kamokuForm = KamokuForm(request.POST) 16 if kamokuForm.is_valid(): 17 Kamoku.objects.create(**kamokuForm.cleaned_data) 18 return redirect('kamoku') 19 context = { 20 'kamokuForm': kamokuForm, 21 'kamokus': Kamoku.objects.all(), 22 } 23 return render(request, 'kamoku.html', context) 24 25 26def kamoku_edit(request, id): 27 kamoku = get_object_or_404(Kamoku, pk=id) 28 kamokuForm = Kamoku_editForm(instance=kamoku) 29 if request.method == 'POST': 30 kamokuForm = Kamoku_editForm(data=request.POST) 31 if kamokuForm.is_valid(): 32 kamoku.kamoku_name = kamokuForm.cleaned_data['kamoku_name'] 33 kamokuForm.save() 34 return redirect('kamoku') 35 36 context = { 37 'kamokus': Kamoku.objects.all(), 38 'kamokuForm': kamokuForm, 39 } 40 return render(request, 'kamoku_edit.html', context)

forms

1from django import forms 2from django.contrib.admin.widgets import AdminDateWidget 3from .models import Kamoku 4 5class KamokuForm(forms.ModelForm): 6 class Meta: 7 model = Kamoku 8 fields = ('kamoku_code', 'kamoku_name') 9 10class Kamoku_editForm(forms.ModelForm): 11 kamoku_code = forms.IntegerField( 12 widget=forms.TextInput( 13 attrs={ 14 'readonly': 'disabled' 15 } 16 ), 17 ) 18 class Meta: 19 model = Kamoku 20 fields = ('kamoku_code', 'kamoku_name')

models

1from django.db import models 2 3class Kamoku(models.Model): 4 kamoku_code = models.IntegerField(blank=False, null=False, primary_key=True, verbose_name="科目コード") 5 kamoku_name = models.CharField(max_length=255,verbose_name="科目名称") 6 created_at = models.DateTimeField(auto_now_add=True) 7 updated_at = models.DateTimeField(auto_now=True) 8 9 def __str__(self): 10 return self.kamoku_name

#実際の画面
イメージ説明

#最後に
更新処理は正しく動いているように思いますが、もしかするとそこがおかしいのかもしれません。
PrimaryKeyを外した場合は更新されることを確認しています。

PrimaryKeyをモデルに設定したことがないため、このような動きが正常なのか、自分の更新処理がおかしいのか判断がつきません。

わかる方が見えましたらご教授ください。

#追記
乗せた画像がものすごくわかりずらいですが、左側の一覧より100で始まるレコードを選択し、更新処理内でPKを指定しているため、右側の画面に情報が出ています。
科目名称という部分のみを変更して更新ボタンを押すと画像のようになります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Python

1if request.method == 'POST': 2 kamokuForm = Kamoku_editForm(data=request.POST) 3```↓ 4```Python 5if request.method == 'POST': 6 kamokuForm = Kamoku_editForm(request.POST, instance=kamoku)

投稿2021/01/10 00:05

ForestSeo

総合スコア2722

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

setuna0531

2021/01/12 03:44

ForestSeo様 ご回答ありがとうございます! 確認したところ無事動かすことが出来ました! とても助かりました! また、今回の回答の質問なのですが、POSTで受け取ったときにデータを渡していないから追加扱いになっていた感じでしょうか?
ForestSeo

2021/01/12 07:05

そうですね。 POST送信時もformにinstanceを渡さないとダメです
setuna0531

2021/01/12 07:35

なるほどですね・・・! IFに入る前で呼び出してるからいけるだろうと思ってました(;^ω^) ありがとうございました!
guest

0

if kamokuForm.is_valid():
kamoku.kamoku_name = kamokuForm.cleaned_data['kamoku_name']
kamokuForm.save()
return redirect('kamoku')

formをセーブするのではなく、モデルインスタンスをセーブすれば良いのではないでしょうか。

追記
言葉足らずでした。フォームをセーブしてしまうと新しいレコードが作成されてしまうと思います。だからモデルを更新したいのならモデルインスタンスにフォームの値を入れてモデルインスタンスをセーブすれば良いと思います。

def kamoku_edit(request, id): kamoku = get_object_or_404(Kamoku, pk=id) #これを変更したいなら kamokuForm = Kamoku_editForm(instance=kamoku) if request.method == 'POST': kamokuForm = Kamoku_editForm(data=request.POST) if kamokuForm.is_valid(): kamoku.kamoku_name = kamokuForm.cleaned_data['kamoku_name'] kamokuForm.save() #kamoku.save()とする return redirect('kamoku')

投稿2021/01/07 17:54

編集2021/01/08 01:50
yaha4967

総合スコア106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

setuna0531

2021/01/08 01:28

yaha4967さん コメントありがとうございます。 >formをセーブするのではなく、モデルインスタンスをセーブすれば良いのではないでしょうか。 →formでPrimaryKeyがついているデータを更新することは不可能という意味でしょうか?  できればFormを利用して保存等をしたいというのはあります。
setuna0531

2021/01/08 03:05

yaha4967さん 追記ありがとうございます! Formをsaveするのではなく、モデルインスタンスをsaveしたのですが、PrimaryKeyが存在していますと出てしまいます。
yaha4967

2021/01/08 04:28

そうですか。モデルを新しく作ったから「PrimaryKeyが存在しています」とでてるのだと思うのですが。。。 最後にsave(force_update=True)を試してみてください。saveにはインサートとアップデートがあるようでforce_update=Trueはアップデートを強制します。 これでできなかったらごめんない。私にはちょっとわからないです。 公式ドキュメントは役立つと思うので他に回答が付かず行き詰まるようでしたら是非みてみてください。 https://docs.djangoproject.com/ja/3.1/ref/models/instances/
setuna0531

2021/01/08 04:46

yaha4967さん お調べしていただきありがとうございます! 確かにモデルを新しく同じコードで作成すると「PrimaryKeyが存在しています」と出ることは確認できています。 yaha4967さんに調べていただいたsave(force_update=True)を試しましたが、Primaryが存在しますとやはり出てしまいました・・・。 公式ドキュメントを一度あさってみます。 お時間使わせてしまいすみませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問