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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

903閲覧

python,DjangoによるAPIデータの保存について

Meteor

総合スコア18

Django

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/12/07 12:29

編集2018/12/08 01:24

python3 django2で商品管理システムを独学で作っています。

あるシステムからAPIデータがjsonで送られてくるのですが、それをDBに保存するところまでの機能を実装したいのですが、上手くDBにまでデータが保存されていません。
APIの送信エラーも出ていないようなので、どこに問題があるのか辿れずにいます。

ご指摘いただけたら幸いです。

views.py

1@csrf_exempt 2def transaction_api(request): 3 if request.method == "POST": 4 5 json_data = json.loads(request.POST["params"]) 6 head_data = json_data["data"][0]["rows"] 7 detail_data = json_data["data"][1]["rows"] 8 9 transaction_head = 0 10 transaction_detail = 0 11 head_flag = 0 12 detail_flag = 0 13 14 # TransactionHead 15 for hd in head_data: 16 head_form = HeadForm(hd) 17 if head_form.is_valid(): 18 head_form.save() 19 head_flag += 1 20 21 if head_flag == len(head_data): 22 transaction_head = 1 23 24 # TransasctionDetail 25 for dd in detail_data: 26 detail_form = DetailForm(dd) 27 if detail_form.is_valid(): 28 detail_form.save() 29 detail_flag += 1 30 31 if detail_flag == len(detail_data): 32 transaction_detail = 1 33 response_data = { 34 "TransactionHead": transaction_head, 35 "TransactionDetail": transaction_detail 36 } 37 return JsonResponse(response_data, safe=False) 38 39 else: 40 response_data = json.dumps({}) 41 return JsonResponse(response_data, safe=False)

forms.py

1 2from .models import TransactionHead, TransactionDetail 3 4class HeadForm(forms.ModelForm): 5 6 class Meta: 7 model = TransactionHead 8 fields = '__all__' 9 10 transactionHeadId = forms.IntegerField(label="取引ID", required=False) 11 transactionDateTime = forms.DateTimeField(label="取引日時", required=False) 12 transactionHeadDivision = forms.CharField(max_length=1, label="取引区分", required=False) 13 updDateTime = forms.DateTimeField(label="更新日時", required=False) 14 15 def save(self, commit=True): 16 instance = super(HeadForm, self).save(commit=False) 17 if commit: 18 instance.save() 19 return instance 20 21 22class DetailForm(forms.ModelForm): 23 24 class Meta: 25 model = TransactionDetail 26 fields = '__all__' 27 28 transactionHeadId = forms.IntegerField(label="取引ID", required=False) 29 transactionDateTime = forms.DateTimeField(label="取引日時", required=False) 30 transactionDetailId = forms.IntegerField(label="取引明細ID", required=False) 31 parentTransactionDetailId = forms.IntegerField(label="親取引明細ID", required=False) 32 transactionDetailDivisio = forms.CharField(max_length=1, label="取引明細区分", required=False) 33 productId = forms.IntegerField(label="商品ID", required=False) 34 productCode = forms.CharField(max_length=20, label="商品コード", required=False) 35 productName = forms.CharField(max_length=85, label="商品名", required=False) 36 37 def save(self, commit=True): 38 instance = super(DetailForm, self).save(commit=False) 39 if commit: 40 instance.save() 41 return instance

models.py

1from django.db import models 2 3class TransactionHead(models.Model): 4 transactionHeadId = models.BigIntegerField(verbose_name="取引ID", null=True) 5 transactionDateTime = models.DateTimeField(verbose_name="取引日時", null=True) 6 transactionHeadDivision = models.CharField(max_length=1, verbose_name="取引区分", null=True) 7 updDateTime = models.DateTimeField(verbose_name="更新日時", null=True) 8 9 10class TransactionDetail(models.Model): 11 transactionHeadId = models.BigIntegerField(verbose_name="取引ID", null=True) 12 transactionDateTime = models.DateTimeField(verbose_name="取引日時", null=True) 13 transactionDetailId = models.IntegerField(verbose_name="取引明細ID", null=True) 14 parentTransactionDetail = models.IntegerField(verbose_name="親取引明細ID", null=True) 15 transactionDetailDivisio = models.CharField(max_length=1, verbose_name="取引明細区分", null=True) 16 productId = models.BigIntegerField(verbose_name="商品ID", null=True) 17 productCode = models.CharField(max_length=20, verbose_name="商品コード", null=True) 18 productName = models.CharField(max_length=85, verbose_name="商品名", null=True)

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

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

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

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

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

guest

回答1

0

ベストアンサー

実際に POST される JSON データとレスポンスのサンプル、 HeadFormDetailForm ・関連 model の定義等、状況を把握するのに必要な情報をひととおりお出しにならないと、他の方が具体的な議論をするのはおそらく難しいのではないかなと思います。

ひとまず一般論の範囲で問題解決のアプローチについてだけ回答させていただきますね。

  • レスポンスだけを見てデバッグするのは大変なので、 logging でも print() でも breakpoint() でも何でもよいので、途中の情報を細かくチェックされるのがよいかと思います。
  • 少なくとも、 request.POST の中身と head_form.save()detail_form.save() の戻り値はチェックされた方がよいかと思います。
  • 開発中は別のシステムから直接 POST するのではなく curl や HTTPie 等でテストされた方がデバッグがスムーズかと思います。

開発中にサーバをいくつもお作りになっているのであれば、実は見るデータベースが間違っていたなんてこともありえると思いますので、改めてチェックされるとよいかもしれません。

ご参考になるでしょうか。

投稿2018/12/07 14:34

gh640

総合スコア1407

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

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

Meteor

2018/12/08 01:30

ご指摘ありがとうございました。追加で記載させていただきました。
gh640

2018/12/10 02:49

追記いただいたところを拝見しました。以下いくつかコメントです。 - パッと見た印象では model / Form クラス / view には「正常なレスポンスが返ってくるのに DB に保存されない問題」につながる原因はなさそうに見えます。 - 「 実際に POST される JSON データとレスポンスのサンプル 」についてはいかがでしょう? - 「少なくとも、 request.POST の中身と head_form.save() と detail_form.save() の戻り値はチェックされた方がよいかと思います。」については試されましたか?どのような結果になりましたか? 主旨から外れますが、 `save()` メソッドはどういう理由で上書きされているのでしょう?
Meteor

2018/12/10 03:11

ありがとうございました。カラム名にいくつか誤りがあったのと、gunicornをrestertしていなかったからだと判明しました。 おかげで何度も見直して問題を発見できました。
gh640

2018/12/10 03:36

そうでしたか。「 gunicorn を restart していなかったため」はよく陥りがちですよね。お役に立てたか怪しいところですが、ともあれ、ご解決されたとのことでよかったです :D
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問