我很难找到使用DRF通过axios将表单数据发布到Django后端的方法。经典Django表单可以正常工作。
每当我尝试使用React Modal表单发布它时,我都会在数据库中得到一个新输入,该输入一直都由None组成(我猜是null)。串行器似乎没有中断它,并且我得到201 HTTP状态。我不知道在哪里寻找这个问题的原因,我相信我已经尝试了几乎所有东西。
我将发布我的代码,以便更有经验的人可以发现此错误的根源。
components.js / lookup.js
import axios from "axios";
const csrftoken = getCookie("csrftoken");
const api = axios.create({
baseURL: `http://localhost:8000`,
headers: {
"X-CSRFToken": csrftoken,
},
});
function getCookie(name) {
// gets csrf cookie
var cookieValue = null;
if (document.cookie && document.cookie !== "") {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
export async function apiLookup(method, endpoint, callback, data) {
try {
if (method === "GET") {
api.get(`${endpoint}`).then((response) => {
callback(response.data, response.status);
});
} else if (method === "POST") {
axios(
{
method: "post",
url: `http://localhost:8000${endpoint}`,
data: data,
},
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
}
} catch (error) {
console.log(error);
}
}
employee / lookup.js
import { apiLookup } from "../lookup";
export async function apiCreateEmployee(callback, data) {
let endpoint = "/api/employee/create-employee";
console.log(data);
apiLookup("POST", endpoint, callback, data);
}
addform.js
import React, { createRef } from "react";
import { apiCreateEmployee } from "./lookup";
export function EmployeeCreate(props) {
const firstNameRef = createRef();
const lastNameRef = createRef();
const departmentRef = createRef();
const positionRef = createRef();
const salaryRef = createRef();
const contactNumberRef = createRef();
const imageRef = createRef();
const { didAddEmployee } = props;
const handleBackendUpdate = (response, status) => {
if (status === 201) {
didAddEmployee(response);
} else {
console.log(response);
alert("An error occured, please try again");
}
};
const handleSubmit = (event) => {
event.preventDefault();
const newEmployee = {
first_name: firstNameRef.current.value,
last_name: lastNameRef.current.value,
department: departmentRef.current.value,
position: positionRef.current.value,
salary: salaryRef.current.value,
contact_number: contactNumberRef.current.value,
image: imageRef.current.files[0],
};
apiCreateEmployee(handleBackendUpdate, newEmployee);
};
const fieldClass = "form-control w-75 p-2 my-2 mx-auto";
return (
<div className={props.className}>
<form
className="w-100 d-flex justify-content-center flex-column align-content-around mx-auto"
onSubmit={handleSubmit}
>
<textarea
ref={firstNameRef}
required={true}
className={fieldClass}
name="first_name"
placeholder="First name"
></textarea>
<textarea
ref={lastNameRef}
required={true}
className={fieldClass}
name="last_name"
placeholder="Last name"
></textarea>
<textarea
ref={departmentRef}
required={true}
className={fieldClass}
name="department"
placeholder="Department"
></textarea>
<textarea
ref={positionRef}
required={true}
className={fieldClass}
name="position"
placeholder="Position"
></textarea>
<textarea
ref={salaryRef}
required={true}
className={fieldClass}
name="salary"
placeholder="Salary"
></textarea>
<textarea
ref={contactNumberRef}
required={true}
className={fieldClass}
name="contact_number"
placeholder="Contact number"
></textarea>
<input
type="file"
ref={imageRef}
required={false}
className={fieldClass}
placeholder="Photo"
></input>
<button type="submit" className="btn btn-primary my-3 w-50 mx-auto">
Add new employee
</button>
</form>
</div>
);
}
employee / serializers.py
from rest_framework import serializers
from .models import Employee
class EmployeeSerializer(serializers.ModelSerializer):
first_name = serializers.SerializerMethodField(read_only=True)
last_name = serializers.SerializerMethodField(read_only=True)
department = serializers.SerializerMethodField(read_only=True)
position = serializers.SerializerMethodField(read_only=True)
salary = serializers.CharField(read_only=True)
contact_number = serializers.CharField(read_only=True)
image = serializers.ImageField(allow_empty_file=True, required=False)
class Meta:
model = Employee
fields = ['first_name', 'last_name', 'department',
'position', 'salary', 'contact_number', 'image']
def get_first_name(self, obj):
return obj.first_name
def get_last_name(self, obj):
return obj.last_name
def get_department(self, obj):
return obj.department
def get_position(self, obj):
return obj.position
def get_salary(self, obj):
return obj.salary
def get_contact_number(self, obj):
return obj.contact_number
def get_image(self, obj):
print(obj.image)
return obj.image
class EmployeeCreateSerializer(serializers.ModelSerializer):
first_name = serializers.SerializerMethodField(read_only=True)
last_name = serializers.SerializerMethodField(read_only=True)
department = serializers.SerializerMethodField(read_only=True)
position = serializers.SerializerMethodField(read_only=True)
salary = serializers.CharField(read_only=True)
contact_number = serializers.CharField(read_only=True)
image = serializers.ImageField(allow_empty_file=True, required=False)
class Meta:
model = Employee
fields = ['first_name', 'last_name', 'department',
'position', 'salary', 'contact_number', 'image']
def validate_salary(self, value):
if not value:
return 0
try:
return int(value)
except ValueError:
raise serializers.ValidationError('You must supply an integer')
def validate_contact_number(self, value):
if not value:
return 0
try:
return int(value)
except ValueError:
raise serializers.ValidationError('You must supply an integer')
def validate_content(self, value):
if len(value) > settings.MAX_TEXT_LENGTH:
raise serializers.ValidationError(
'Maximum text length exceeded.')
return value
def get_first_name(self, obj):
return obj.first_name
def get_last_name(self, obj):
return obj.last_name
def get_department(self, obj):
return obj.department
def get_position(self, obj):
return obj.position
def get_salary(self, obj):
return obj.salary
def get_contact_number(self, obj):
return obj.contact_number
def get_image(self, obj):
print(obj.image)
return obj.image
employee / models.py
from django.db import models
class EmployeeManager(models.Manager):
def get_queryset(self):
return EmployeeQuerySet(self.model, using=self._db)
def search(self, query=None):
return self.get_queryset().search(query=query)
class EmployeeQuerySet(models.QuerySet):
def search(self, query=None):
qs = self
if query is not None:
or_lookup = (Q(first_name__icontains=query) | Q(
last_name__icontains=query))
qs = qs.filter(or_lookup).distinct()
return qs
class Employee(models.Model):
first_name = models.CharField(blank=False, null=True, max_length=30)
last_name = models.CharField(blank=False, null=True, max_length=30)
department = models.CharField(blank=False, null=True, max_length=50)
position = models.CharField(blank=False, null=True, max_length=30)
salary = models.CharField(blank=False, max_length=10)
contact_number = models.CharField(blank=False, max_length=10)
image = models.ImageField(
default='profile_pic.jpg', upload_to='employee_photos')
def __str__(self):
return f'{self.first_name} {self.last_name}'
objects = EmployeeManager()
我很乐意发布其他任何内容,但我认为问题可能出在那些文件中。
非常感谢您对解决方案的贡献。
欢呼
答案 0 :(得分:1)
除了下面的代码段,这对您的代码毫无用处
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = ['first_name', 'last_name', 'department',
'position', 'salary', 'contact_number', 'image']
检查您的视图是否有多部分解析器。
检查docs以获取更多信息
尝试记录您的request.data以检查真正在axios上发布的数据。