【Django Rest Framework】新規登録機能API実装で400エラー
解決したいこと
→フロントエンド:Vue.js
→バックエンド:Django Rest Framework
400エラーがでてしまったので解決したいです
エラー内容
POST http://localhost:8000/api/resister/ 400 (Bad Request)
dispatchXhrRequest @ xhr.js:251
xhr @ xhr.js:49
dispatchRequest @ dispatchRequest.js:51
request @ Axios.js:148
httpMethod @ Axios.js:187
wrap @ bind.js:5
resister @ MemberForm.vue:133
callWithErrorHandling @ runtime-core.esm-bundler.js:173
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:182
emit @ runtime-core.esm-bundler.js:730
eval @ runtime-core.esm-bundler.js:7465
handleClick @ use-button.ts:57
callWithErrorHandling @ runtime-core.esm-bundler.js:173
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:182
invoker @ runtime-dom.esm-bundler.js:345
MemberForm.vue:145 APIリクエストが失敗しました
エラー内容
ソースコード
<template>
<div class="member-form-container">
<h2>新規登録</h2>
<img
src="@/assets/スタート.jpg"
alt="SAY HELLO TO BIKE ロゴ"
style="width: 30%"
/>
<ul id="example-1">
<li v-for="message in validationErrors.validates" :key="message">
{{ message }}
</li>
</ul>
<!-- <el-form :model="form" class="custom-form" style="width: 40%"> -->
<el-form class="custom-form" style="width: 30%">
<el-form-item label="ニックネーム" class="custom-form-item">
<el-input
v-model="init.nickname"
placeholder="ニックネームを入力してください"
class="custom-input"
/>
</el-form-item>
<el-form-item label="メールアドレス" class="custom-form-item">
<el-input
v-model="init.email"
placeholder="メールアドレスを入力してください"
class="custom-input"
/>
</el-form-item>
<el-form-item label="パスワード" class="custom-form-item">
<el-input
v-model="init.password"
placeholder="パスワードを入力してください"
class="custom-input"
/>
</el-form-item>
<el-form-item label="パスワード(確認)" class="custom-form-item">
<el-input
v-model="init.passwordconfirm"
placeholder="パスワードを入力してください"
class="custom-input"
/>
</el-form-item>
<p>好きな観光地について書いてください</p>
<el-form-item class="custom-form-item">
<el-input
v-model="init.favorite"
placeholder="好きな観光地について書いてください"
:autosize="{ minRows: 2, maxRows: 5 }"
class="custom-input"
type="textarea"
/>
</el-form-item>
<el-form-item class="custom-form-item">
<el-date-picker
v-model="init.birth_day"
type="date"
placeholder="誕生日を選択してください"
class="custom-picker"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<div class="fileInput-container">
<input
type="file"
@change="handleFileUpload($event)"
accept="image/*"
capture
/>
</div>
</el-form>
<div class="button-container">
<el-button @click="resister" type="primary">登録</el-button>
<el-button @click="logout" type="primary">TOP</el-button>
</div>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
import { reactive, computed, ref } from "vue";
import "element-plus/dist/index.css";
import validations from "@/module/validate";
import axios from "axios";
// Axiosの設定
axios.defaults.withCredentials = true;
const file = ref(null);
const router = useRouter();
const init = reactive({
nickname: "",
email: "",
password: "",
passwordconfirm: "",
favorite: "",
birth_day: "",
});
const validationErrors = computed(() => {
const errors = {
validates: [],
};
validations.emailValidate(init.email, errors.validates);
validations.passwordValidate(init.password, errors.validates);
return errors;
});
// ファイルをアップロードする準備をする
const handleFileUpload = ($event) => {
file.value = $event.target.files[0];
};
const resister = () => {
// フォームのデータをAPIに送信する処理
const data = {
user: {
username: init.nickname,
email: init.email,
password: init.password,
},
// email: init.email,
// password: init.password,
favorite: init.favorite,
birth_day: init.birth_day,
image: file.value,
};
console.log("request",data);
// APIエンドポイントに対してPOSTリクエストを送信
// @TODO API実装後に保存
axios
.post("http://localhost:8000/api/resister/", data, {
headers: {
"Content-Type": "multipart/form-data", // ファイルを含むフォームデータの場合は必要
},
})
.then((response) => {
// 成功時の処理
console.log("APIリクエストが成功しました", response.data);
})
.catch((error) => {
// エラー時の処理
console.error("APIリクエストが失敗しました", error);
});
view.py
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser
from .models import UserInfo
from .serializer import UserInfoSerializer, UserSerializer
# ロガーの設定
import logging
# ロガーの設定
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) # デバッグレベルのログを出力
class UserInfoViewSet(viewsets.ModelViewSet):
queryset = UserInfo.objects.all()
serializer_class = UserInfoSerializer
parser_classes = [MultiPartParser] # ファイルアップロード用のパーサーを追加
def create(self, request, *args, **kwargs):
user_data = request.data.get('user')
user_serializer = UserSerializer(data=user_data)
if user_serializer.is_valid():
user = user_serializer.save()
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save(user=user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
selializer.py
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import UserInfo
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email', 'password']
extra_kwargs = {'password': {'write_only': True}}
class UserInfoSerializer(serializers.ModelSerializer):
user = UserSerializer() # Userモデルのシリアライザーをネスト
class Meta:
model = UserInfo
# json で出力するフィールド
fields = ('id','user', 'birth_day','favorite','created_at' ,'image')
def update(self, instance, validated_data):
# userフィールドのデータを取得
user_data = validated_data.pop('user', None)
if user_data:
# userフィールドの更新処理を実装
instance.user.username = user_data.get('username', instance.user.username)
instance.user.email = user_data.get('email', instance.user.email)
instance.user.save()
# インスタンスを保存して更新したデータを返す
instance.save()
return instance
def delete(self, instance):
instance.delete()
確認したこと
1.headerがあっているか
"Content-Type": "multipart/form-data",
2.リクエストパラメータは合致しているか
3.view.pyのcreateメソッドは正常によばれているか
等を確認しましたが400エラーが解消されません。
さいごに
今回画像とテキストを混ぜてリクエストを送っているため、その辺が不安です
お忙しいところ恐縮ですが宜しくお願い致します。
0