无法从react-select向django rest框架提交表单数据中的数组

a64a0gku  于 2023-06-07  发布在  Go
关注(0)|答案(1)|浏览(176)

我正在使用React/Django构建一个应用程序,并使用DRF和Form数据将数据从React表单发布到Django模型。我使用了包含多个选择的React select,因为我想将数据发送到Django中的manytomany字段
models.py:

class classification(models.Model):
    theclass = models.CharField(max_length=200) 
    def __str__ (self):
        return self.theclass
    @property
    def classification_dictionary(self):
        return {'label':self.theclass , 'value': self.id}

 class book(models.Model):
        name = models.CharField(max_length=499)
        bookClassification = models.ManyToManyField('classification', blank=True)
        def __str__ (self):
            return self.name

serializers.py:

class BookSerializer(serializers.ModelSerializer):

    bookClassification = serializers.SlugRelatedField(
        many=True,
        read_only = True,
        slug_field='classification_dictionary'
    )
    class Meta:
        model = book
        fields = '__all__'

views.py (theapi):

class BookFormViewSet(APIView):
    permission_classes = [AllowAny]
    authentication_classes = [TokenAuthentication]
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    @csrf_exempt
    def post(self, request, format=None):
        serializer = BookFormSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            
            return Response(serializer.data,status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是后端,以下是React前端部分:

import React from "react";
import Select from 'react-select';
import axios from "axios";
import { useForm, Controller } from "react-hook-form";
import { TextField, Checkbox } from "@material-ui/core";

export default function BookForm(){

    const [classificationOptions, setClassificationOptions] = React.useState([])
    const [entryClass, setEntryClass] =React.useState([])
   
    React.useEffect (function(){
   
        fetch('/classification')
        .then(res => res.json())
        .then(data => {
            data.map(theclass => {
           let newClass = {value: `${theclass.id}`, label: `${theclass.theclass}`}  
           setClassificationOptions(oldArray => [...oldArray, newClass]) 
        })
        })

       
    }, [])

          const onSubmit= (data) => {
            console.log(data)
        let classArray = []
        data.bookClassification.map(option => {
          classArray.push(option.value)
        })
            let form_data = new FormData();
        form_data.append('name', data.name);
        form_data.append('bookClassification', classArray);
        console.log(form_data)
            axios.post('/postbook/', form_data, {
              headers: {
                  'Content-Type': 'multipart/form-data'
              }
          }).then(res => {
              console.log(res.data);
         
          }).catch(err => {
              console.log(err.response.data);
            console.log('working')
          })
        
  
          }
        
    return(
        <div>
            <form style={styles.book}onSubmit={handleSubmit(onSubmit)}>
                <div>
                
                    <label className="inputLabel">
                        bookName:
                        <input className="inputForm" type="text" {...register("name", { required: true })}/>
                    </label>
                    {errors.name && <span>This field is required</span>}
                </div>

                <div>
                    <h4>book classification:</h4>
                <Controller
                name="bookClassification"
                control={control}
                rules={{ required: true }}
                render={({ field }) => 
                <Select
                    isMulti
                    {...field} 
                   options={classificationOptions}
                        />
            
            }
            />
            {errors.bookClassification && <span>This field is required</span>}

                </div>
                
                <div>
                    <input type="submit" />
                </div>
            </form>
               
        </div>
    )
}

前端的表单数据没有将图书分类的值作为数组发送,而是将其作为字符串发送,当我提交console.log form_Data时,我发现了这个问题:

FormData { name → "name", bookClassification → "1,3" }

console.log的响应(错误)结果是:

bookClassification: Array [ "Incorrect type. Expected pk value, received str." ]

我尝试在bookclassification的值之前使用JSON.stringfy和Array,但没有任何效果。那么我如何通过表单数据发送数组呢

hmmo2u0o

hmmo2u0o1#

在将bookClassification值发送到BookFormSerializer之前修改该值。

class BookFormViewSet(APIView):
    permission_classes = [AllowAny]
    authentication_classes = [TokenAuthentication]
    parser_classes = [MultiPartParser, FormParser, JSONParser]

    @csrf_exempt
    def post(self, request, format=None):
        data = request.data
        data['bookClassification'] = request.data.get("bookClassification").split(",")

        serializer = BookFormSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
        
        return Response(serializer.data,status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

相关问题