我必须处理application/jsonmultiform/data,student_image: fileState,其中fileStatee.target.file[0]的值,这是图像和其他字段只有application/json将存储,但这fileState需要multiform/data,即使在改变后,我的图像也没有存储在数据库中.当我的API接受List对象时,如何将数据发送到API.在DRF中存储图像和models.py中的其他字段值有什么其他 idea 吗?

const handleSubmit = () => {
  let dataToSend = {};
          
  if (Array.isArray(formData)) {
    // Handle array data
    dataToSend = formData.map((formFields, index) => ({
    //     // Map the fields accordingly for each object in the array
    //     // Adjust this based on your data structure
      sn: formFields.sn,
      student_image: fileState,
      // Add other fields as needed
    }));
  } else if (typeof formData === 'object') {
    // dataToSend = [formData]
    // Handle object data
    dataToSend = [{
      // Map the fields accordingly for the object
      // Adjust this based on your data structure
      nepali: formData.nepali,
      international: formData.international,
      graduate_school_or_campus: formData.Campus,
      student_image: fileState,
      first_name: formData.first_name,
      middle_name: formData.middle_name,
      last_name: formData.last_name,
      email: formData.email,
      contact_no: formData.contact_no,
      gender: formData.gender,
      blood_group: formData.blood_group,
      ethnicity: formData.ethnicity,
      religion: formData.religion,
      date_of_birth_bs: formData.date_of_birth_bs,
      date_of_birth_ad: formData.date_of_birth_ad,
      batch: formData.batch,
      disability_status: formData.disability_status,
      sponsorship_status: formData.sponsorship_status,
      rural_district: formData.rural_district,
      martyr_lineage: formData.martyr_lineage,
      // citizenship_no: citizenship_no,
      // citizenship_image: formData.citizenship_image,
      school: formData.school,
      level: formData.level,
      program: formData.program,
      semester: formData.semester,
      status: formData.status,
      // 
      father_name: formData.father_name,
      mother_name: formData.mother_name,
      father_phone: formData.father_phone,
      mother_phone: formData.mother_phone,
      father_email: formData.father_email,
      mother_email: formData.mother_email,
      father_profession: formData.father_profession,
      mother_profession: formData.mother_profession,
      emergency_contact_name: formData.emergency_contact_name,
      emergency_contact_phone: formData.emergency_contact_phone,
      address: formData.address,
      relation_with_student: formData.relation_with_student,
      permanent_province: formData.permanent_province,
      permanent_district: formData.permanent_district,
      permanent_palika: formData.permanent_palika,
      permanent_ward_no: formData.permanent_ward_no,
      permanent_street_name: formData.permanent_street_name,
      permanent_house_no: formData.permanent_house_no,
      present_province: formData.present_province,
      present_district: formData.present_district,
      present_palika: formData.present_palika,
      present_ward_no: formData.present_ward_no,
      present_street_name: formData.present_street_name,
      present_house_no: formData.present_house_no,
      remarks: formData.remarks,
      education_history: formData.nestedForms,
      awardsMeritsScholarship: formData.nestedForms2
      // Add other fields as needed
    }];     
  }
        
  console.log('this is actual data', dataToSend);
  console.log('Type of dataToSend:', typeof dataToSend);
  // Now you can send a POST request with dataToSend to your APIw
  // For example using Axios or fetch
  // Replace 'YOUR_API_URL' with the actual API endpoint
  // Replace 'YOUR_ACCESS_TOKEN' with any authorization token you might need
  console.log("this is final data to sent", dataToSend)
  fetch(`${URL}`, {
    method: 'POST',
    headers: {
      // 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', // Adjust the content type
      'Content-Type': 'application/json', // Adjust the content type
      'Authorization': `Bearer${Ttoken.access}`
    },
    body: JSON.stringify(dataToSend),
  })
    .then(response => response.json())
    .then(data => {
      console.log('Response from API:', data);
      // Additional logic after receiving a response from the API
    })
    .catch(error => {
      console.error('Error:', error);
      // Handle errors from the API call
    });
};

推荐答案

您正在try 将JSON和文件数据发送到Django rest框架(DRF)API,但在数据库中存储图像时遇到了问题.您正在使用FETCH进行API调用.同样,你可能会发现很难继续这样做.从这个意义上说,你可以用DRF的适当方式发送它们.

Backend (Django DRF)

在您的mods.py中,使用ImageField来存储图像.Django 能够自己处理这些问题.


    from django.db import models

    class Student(models.Model):
        student_image = models.ImageField(upload_to='student_images/')
        # other fields

Ensure that your serializers.py also recognizes this field.

Frontend (JavaScript)

您需要更改Content-Type并使用FormData来发送JSON和文件.

下面是修改handleSubmit函数的方法:


const handleSubmit = () => {
  const formDataToSend = new FormData();

  if (typeof formData === 'object') {
    Object.keys(formData).forEach(key => {
      formDataToSend.append(key, formData[key]);
    });
  }
  
  // Add the file to the FormData object
  formDataToSend.append('student_image', fileState);

  // Remove the 'Content-Type' from the headers
  fetch(`${URL}`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${Ttoken.access}`
    },
    body: formDataToSend,
  })
  .then(response => response.json())
  .then(data => {
    console.log('Response from API:', data);
  })
  .catch(error => {
    console.error('Error:', error);
  });
};

Quick Points:

  • 删除'Content-Type': 'application/json',因为浏览器将 使用FormData时自动设置此项.
  • 使用FormData发送文件和其他数据.请注意 .append()可用于单独添加每个字段.
  • 在Django模型中使用ImageField来处理图像文件.
  • 用于授权的令牌不变.

有了这些更改,您应该能够将文件和JSON数据发送到DRF API并相应地存储它们.

为什么?

最主要的问题是您要发送的数据格式与您的API设计用于处理的数据格式之间的不一致.具体地说,就是:

  • 您试图在单个API中同时发送JSON和文件数据 使用‘app/json’内容类型的请求,这不会 对于文件上传来说就足够了.
  • 后端没有指定,但它应该准备好处理 这种多部分的数据.合适的字段类型,如ImageField 在Django中,需要REST框架的模型来处理 高效地获取图像数据.

这些差异使得在数据库中有效地存储图像和JSON数据变得困难.

其他解决方案

如果您确实想保持原有的方式,并且仍然在数据有效负载中包含图像,一种常见的方法是将图像编码为Base64字符串.此方法允许您将图像作为字符串与其他字段一起发送,从而简化了数据处理,使其在不同平台和浏览器之间更兼容.但是,也存在一些权衡,例如增加了数据大小(大约比原始文件大33%),以及编码和解码过程需要额外的CPU使用量.我不会全面推荐,但请 Select 最适合您的设置.

Backend

在实现方面,您可以修改Django模型以使用TextField来存储Base64编码的图像.


from django.db import models

class Student(models.Model):
    student_image_base64 = models.TextField()

Frontend

对于前端部分,您可以使用JAVASCRIPT的FileReader来读取图像文件并获得其Base64表示.然后,将该字符串包括在您的Fetch API调用中发送的JSON对象中.下面是如何调整handleSubmit函数的方法:


const handleSubmit = async () => {
  const reader = new FileReader();
  reader.readAsDataURL(fileState);
  reader.onload = async () => {
    const base64String = reader.result.split(',')[1];
    let dataToSend = {
      student_image_base64: base64String,
      // your other fields here
    };

    await fetch(`${URL}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${Ttoken.access}`
      },
      body: JSON.stringify(dataToSend),
    })
    .then(response => response.json())
    .then(data => {
      console.log('Response from API:', data);
    })
    .catch(error => {
      console.error('Error:', error);
    });
  };
};

使用这种方法,您实际上是在将图像转换为一种可以轻松与其他类型的数据一起发送的格式,从而简化了整个数据处理过程. Select 更适合您的设置和理想的.

Reactjs相关问答推荐

实时收听react前端应用程序中的webhook响应

如何使用mui为可重复使用的react 按钮应用不同的风格

ReferenceError:未在Redux组件中定义窗口

react 派生状态未正确更新

如何处理具有REACTION-REDUX状态的Nextjs路由警卫

react ';S使用状态不设置新状态

在ReactJS的monaco编辑器中添加美人鱼语法

为 Next.js 应用程序目录中的所有页面添加逻辑的全局文件是什么?

Mui 在 TextField 标签上添加工具提示显示两个工具提示框

如何在next.js 13中仅在主页导航栏上隐藏组件?

如何在Next.js应用程序中为路由[slug]生成.html文件?

CORS策略:对预检请求的响应未通过访问控制判断:没有Access-Control-Allow-Origin

如何修改 react/jsx-no-useless-fragment 规则以允许 <>{children}

如何在屏幕上使用相同的可重用

无法读取未定义的react native 的属性参数

我应该使用 useEffect 来为 React Native Reanimated 的 prop 值变化设置动画吗?

react 事件顺序

更新和删除功能不工作 Asp.net MVC React

在 React 中,为什么不能向空片段添加键(短语法)?

理解 React 中的 PrevState