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

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

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

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

1261閲覧

AxiosのPOSTリクエストから、1対多若しくは多対多のインスタンスを作成する方法(React, Django)

Toshiyuki023

総合スコア3

Django

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/09/14 12:43

ソースコード

models

1class CustomUserManager(UserManager): 2 3 ## 省略 4 5 6# Django提供のカスタムユーザーのFieldを決定 7class User(AbstractUser): 8 username = models.CharField(max_length=150, unique=True) 9 email = models.EmailField(max_length=100, unique=True) 10 profile = models.TextField(max_length=800, blank=True, null=True) 11 icon = models.ImageField(blank=True, null=True) 12 background = models.ImageField(blank=True, null=True) 13 14 15 ## 省略 16 17 18 19class Bland(models.Model): 20 name = models.CharField(max_length=100) 21 22 def __str__(self): 23 return self.name 24 25 class Meta: 26 db_table = "blands" 27 28 29 30class Keyword(models.Model): 31 name = models.CharField(max_length=100) 32 33 def __str__(self): 34 return self.name 35 36 class Meta: 37 db_table = "keywords" 38 39 40class Want_Item(models.Model): 41 url = models.URLField(max_length=250, null=True, blank=True) 42 parent_item = models.ForeignKey( 43 "Parent_Item", null=True, on_delete=models.CASCADE, related_name="want_item") 44 created_at = models.DateTimeField(auto_now_add=True) 45 updated_at = models.DateTimeField(auto_now=True) 46 47 def __str__(self): 48 return self.parent_item.name 49 50 class Meta: 51 db_table = "want_items" 52 53 54class Parent_Item(models.Model): 55 name = models.CharField(max_length=100) 56 owner = models.ForeignKey( 57 settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, related_name="item") 58 keyword = models.ManyToManyField(Keyword, related_name="parent_item") 59 bland = models.ForeignKey( 60 Bland, related_name="parent_item", on_delete=models.SET_NULL, null=True) 61 request_deal = models.ForeignKey( 62 "Request_Deal", null=True, on_delete=models.CASCADE, related_name="parent_item") 63 created_at = models.DateTimeField(auto_now_add=True) 64 updated_at = models.DateTimeField(auto_now=True) 65 66 def __str__(self): 67 return self.name 68 69 class Meta: 70 db_table = "parent_items" 71

serializers

1class UserSerializer(serializers.ModelSerializer): 2 class Meta: 3 model = User 4 fields = "__all__" 5 write_only_fields = ('password') 6 read_only_fields = ['id'] 7 8 def validate_username(self, value): 9 if len(value) <= 5: 10 raise serializers.ValidationError("ユーザーネームは5文字以上で入力してください") 11 return value 12 13 def validate_password(self, value): 14 if len(value) <= 7: 15 raise serializers.ValidationError("パスワードは最低8文字以上で入力してください") 16 return value 17 18 def create(self, validated_data): 19 password = validated_data.get('password') 20 validated_data['password'] = make_password(password) 21 return User.objects.create(**validated_data) 22 23 # def validate(self, data): 24 # if data.get('password') != data.get('confirm_pass'): 25 # raise serializers.ValidationError("パスワードが一致しません") 26 # return data 27 28 29 30class BlandSerializer(serializers.ModelSerializer): 31 class Meta: 32 model = Bland 33 fields = "__all__" 34 35 def validate_name(self, value): 36 if len(value) == 0: 37 raise serializers.ValidationError("ブランド名は必ず1文字入力してください") 38 return value 39 40 41class KeywordSerializer(serializers.ModelSerializer): 42 class Meta: 43 model = Keyword 44 fields = ["id", "name"] 45 46 def validate_name(self, value): 47 if len(value) <= 1: 48 raise serializers.ValidationError("キーワードは必ず2文字以上で設定してください") 49 return value 50 51 52 53class Want_ItemSerializer(serializers.ModelSerializer): 54 parent_item = serializers.StringRelatedField() 55 56 class Meta: 57 model = Want_Item 58 fields = "__all__" 59 60 61 62class Parent_ItemSerializer(serializers.ModelSerializer): 63 owner = serializers.StringRelatedField() 64 keyword = serializers.StringRelatedField(many=True) 65 bland = serializers.StringRelatedField() 66 request_deal = serializers.StringRelatedField() 67 68 class Meta: 69 model = Parent_Item 70 fields = "__all__" 71 72 def validate_name(self, value): 73 if len(value) <= 4: 74 raise serializers.ValidationError("商品名は必ず5文字以上入力してください") 75 return value 76 77

Reactのフォーム送信のコンポーネントです。

add_want_item

1class Add_Want_Item_Form extends Component { 2 constructor(props) { 3 super(props); 4 this.state = { 5 // #インプット情報用 6 info: { 7 name: '', 8 owner: '', 9 keyword1: '', 10 keyword2: '', 11 bland: '', 12 url: '', 13 }, 14 // Validation用 15 message: { 16 name: '', 17 keyword1: '', 18 keyword2: '', 19 bland: '', 20 }, 21 }; 22 this.handleChange = this.handleChange.bind(this); 23 this.handleSubmit = this.handleSubmit.bind(this); 24 } 25 26 componentDidMount() { 27 axios 28 .get('http://localhost:8000/api/user/' + localStorage.getItem('uid')) 29 .then((res) => { 30 this.setState({ ...this.state, info: { ...this.state.info, owner: res.data } }); 31 console.log(this.state.info.owner); 32 }) 33 .catch((err) => console.log(err)); 34 } 35 36 handleChange(e) { 37 const name = e.target.name; 38 const value = e.target.value; 39 const { info, message } = this.state; 40 this.setState({ 41 info: { ...info, [name]: value }, 42 }); 43 this.setState({ 44 message: { ...message, [name]: this.validator(name, value) }, 45 }); 46 } 47 48 handleSubmit = async () => { 49 let bland; 50 let keyword1; 51 let keyword2; 52 let parentItem; 53 54 await axios 55 .post('http://localhost:8000/api/bland/', { 56 name: this.state.info.bland, 57 }) 58 .then((res) => { 59 bland = res.data.id; 60 console.log('Bland is ' + bland); 61 }) 62 .catch((err) => { 63 console.log(err); 64 }); 65 66 await axios 67 .post('http://localhost:8000/api/keyword/', { 68 name: this.state.info.keyword1, 69 }) 70 .then((res) => { 71 keyword1 = res.data; 72 console.log('Keyword1 is ' + keyword1); 73 }) 74 .catch((err) => { 75 console.log(err); 76 }); 77 78 await axios 79 .post('http://localhost:8000/api/keyword/', { 80 name: this.state.info.keyword2, 81 }) 82 .then((res) => { 83 keyword2 = res.data; 84 console.log('Keyword2 is ' + keyword2); 85 }) 86 .catch((err) => { 87 console.log(err); 88 }); 89 90 axios 91 .post('http://localhost:8000/api/parent/', { 92 name: this.state.info.name, 93 owner: this.state.info.owner, 94 bland: bland, 95 keyword: [keyword1, keyword2] 96 }) 97 .then((res) => { 98 parentItem = res.data; 99 console.log('Parent is ' + parentItem); 100 }) 101 .catch((err) => { 102 console.log(err); 103 }); 104 105 // axios 106 // .post('http://localhost:8000/api/wantitem/', { 107 // url: this.state.info.url, 108 // parent_item: parentItem, 109 // }) 110 // .then((res) => { 111 // const wantItem = res.data; 112 // console.log('wantItem is ' + wantItem); 113 // }) 114 // .catch((err) => { 115 // console.log(err); 116 // }); 117 118 this.setState({ 119 info: { 120 name: '', 121 keyword1: '', 122 keyword2: '', 123 bland: '', 124 url: '', 125 }, 126 }); 127 }; 128 129 render() { 130 const { info, message } = this.state; 131 if (this.state.info.owner === '') { 132 return null; 133 } else { 134 return ( 135 <div> 136 <label>商品名</label> 137 <input 138 name="name" 139 type="text" 140 value={this.state.info.name} 141 onChange={this.handleChange} 142 /> 143 <p>{this.state.message.name}</p> 144 145 <p>{this.state.message.keyword1}</p> 146 <p>{this.state.message.keyword2}</p> 147 <label>キーワード1</label> 148 <input 149 name="keyword1" 150 type="text" 151 value={this.state.info.keyword1} 152 onChange={this.handleChange} 153 /> 154 155 <label>キーワード2</label> 156 <input 157 name="keyword2" 158 type="text" 159 value={this.state.info.keyword2} 160 onChange={this.handleChange} 161 /> 162 163 <label>ブランド</label> 164 <input 165 name="bland" 166 type="text" 167 value={this.state.info.bland} 168 onChange={this.handleChange} 169 /> 170 <p>{this.state.message.bland}</p> 171 172 <label>商品参考URL</label> 173 <input name="url" type="text" value={this.state.info.url} onChange={this.handleChange} /> 174 <input type="button" value="登録" onClick={this.handleSubmit} /> 175 </div> 176 ); 177 } 178 } 179} 180 181const mapStateToProps = (state) => { 182 return { 183 uid: state.uid, 184 loading: state.loading, 185 error: state.error, 186 }; 187}; 188 189export default connect(mapStateToProps)(Add_Want_Item_Form); 190

環境

axios: "0.20.0",
react: "16.13.1"
Django:"3.1.1"
djangorestframework:"3.11.1"

やりたいこと

axios.postのPOSTリクエストから、リレーションを持つオブジェクトを作成したいです。

今回、問題となるリレーションを持つオブジェクトはWant_Item, Parent_Itemです。
Parent_ItemUser,Keyword, Blandを外部キーに持っていて、Want_ItemはそのParent_Itemを外部キーに持ちます。

性質上、Bland,Keywordを先に作成した後Parent_Itemと関連付ける、そしてその後にParent_ItemWant_Itemを関連付けることになるので、async/awaitで非同期処理をしています。

できないこと

POSTリクエスト送信時に、

500 Internal Server Error

というエラーが出て、オブジェクトの作成に失敗しています。
送信する際のKeyword,Bland,Useridやオブジェクト自身で送信したのですが、いずれの方法も同じエラーが返ってきてしまいます。

送信内容が正しくないためにサーバー側からエラーが返ってきているのは間違いないとは思いますが、axios.postの送信内容をどのように修正すれば良いかが分かりません。

お知恵をお貸しいただければ幸いです。
ご回答よろしくお願い申し上げます。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問