我有以下的Django模型
class Component(models.Model):
parent = models.ForeignKey(
"self", on_delete=models.CASCADE, null=True, blank=True, related_name="children"
)
vessel = models.ForeignKey(
Vessel, on_delete=models.CASCADE, related_name="components"
)
name = models.CharField(max_length=100)
manufacturer = models.CharField(max_length=255, null=True, blank=True)
model = models.CharField(max_length=255, null=True, blank=True)
type = models.CharField(max_length=255, null=True, blank=True)
serial_number = models.CharField(max_length=255, null=True, blank=True)
supplier = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
image = models.ImageField(upload_to="component_images", blank=True, null=True)
def __str__(self):
return self.name
此视图集如下所示
class ComponentViewSet(viewsets.ModelViewSet):
serializer_class = ComponentSerializer
def get_queryset(self):
queryset = Component.objects.all()
vessel_id = self.kwargs.get("vessel_id", None)
if vessel_id is not None:
queryset = queryset.filter(vessel_id=vessel_id)
queryset = queryset.filter(Q(parent=None) | Q(parent__isnull=True))
return queryset
def retrieve(self, request, pk=None, vessel_id=None):
queryset = Component.objects.all()
component = get_object_or_404(queryset, pk=pk, vessel_id=vessel_id)
serializer = ComponentSerializer(component)
return Response(serializer.data)
def update(self, request, pk=None, vessel_id=None, partial=True):
queryset = Component.objects.all()
component = get_object_or_404(queryset, pk=pk, vessel_id=vessel_id)
serializer = ComponentSerializer(component, data=request.data, partial=partial)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=["delete"])
def delete_component(self, request, pk=None, vessel_id=None):
queryset = Component.objects.all()
component = get_object_or_404(queryset, pk=pk, vessel_id=vessel_id)
# Recursively delete all children of the component
self._delete_children(component)
# Delete the component itself
component.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
def _delete_children(self, component):
children = component.children.all()
for child in children:
self._delete_children(child)
child.delete()
序列化程序:
class ImageSerializerField(serializers.Field):
def to_representation(self, value):
if not value:
return None
if settings.MEDIA_URL in value.url:
return (
settings.BASE_URL
+ settings.MEDIA_URL
+ value.url[len(settings.MEDIA_URL) :]
)
return value.url
def to_internal_value(self, data):
return data
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class ComponentSerializer(serializers.ModelSerializer):
children = RecursiveField(many=True)
image = ImageSerializerField()
class Meta:
model = Component
fields = "__all__"
这是我用来创建组件的简单react 表单
import React, { useState } from "react";
import { api } from "../../../../../userAuth/auth";
import { useParams } from "react-router";
const ComponentData = () => {
const { vessel_id } = useParams();
const [formData, setFormData] = useState({
vessel: vessel_id,
name: "",
manufacturer: "",
model: "",
type: "",
serial_number: "",
supplier: "",
description: "",
image: null,
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevFormData) => ({
...prevFormData,
[name]: value,
}));
};
const handleImageChange = (e) => {
const file = e.target.files[0];
setFormData((prevFormData) => ({
...prevFormData,
image: file,
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const { children, ...data } = formData; // Exclude the 'children' field
const response = await api.post(
`/maintenance/${vessel_id}/components/`,
data
);
// TODO: Handle successful creation (e.g., show success message, redirect, etc.)
} catch (error) {
console.error("Error creating component:", error);
// TODO: Handle error (e.g., show error message, etc.)
}
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
required
/>
</label>
<br />
<label>
Manufacturer:
<input
type="text"
name="manufacturer"
value={formData.manufacturer}
onChange={handleChange}
/>
</label>
<br />
<label>
Model:
<input
type="text"
name="model"
value={formData.model}
onChange={handleChange}
/>
</label>
<br />
<label>
Type:
<input
type="text"
name="type"
value={formData.type}
onChange={handleChange}
/>
</label>
<br />
<label>
Serial Number:
<input
type="text"
name="serial_number"
value={formData.serial_number}
onChange={handleChange}
/>
</label>
<br />
<label>
Supplier:
<input
type="text"
name="supplier"
value={formData.supplier}
onChange={handleChange}
/>
</label>
<br />
<label>
Description:
<textarea
name="description"
value={formData.description}
onChange={handleChange}
/>
</label>
<br />
<label>
Image:
<input
type="file"
name="image"
accept="image/*"
onChange={handleImageChange}
/>
</label>
<br />
<button type="submit">Create Component</button>
</form>
);
};
export default ComponentData;
每当我发送POST请求时,我都会收到错误的请求.当我判断里面的请求控制台时,会看到以下内容.
response
:
config
:
{transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}
data
:
children
:
['This field is required.']
[[Prototype]]
:
Object
我假设它谈论的是递归字段父级,但我已经在我的模型中声明了它不是必需的,所以我不确定我遗漏了什么.