我正在構建一個 Web 應用程式并嘗試將 Post 資料作為FormData發送到 Django Rest Framework Serializer。在request.data中,我看到所有 Post 資料都在那里,但是在驗證并保存序列化程式之后,似乎有些資料沒有傳遞到valid_data。
視圖.py
@api_view(["GET","POST"])
def api_list(request):
if request.method=="GET":
data = Recipe.objects.all()
serializer = RecipeSerializer(data, many=True)
return Response(serializer.data)
elif request.method=="POST":
print("POST recieved")
print (request.data) <----See below
serializer = RecipeSerializer(data=request.data)
print("Validating..")
if serializer.is_valid():
print("validated!")
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
print (serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
請求資料
<QueryDict:
{'description': ['"gfdgdfg"'],
'name': ['"fdgdfgdf"'],
'ingredients': [
'{"name":"dfgdfg","amount":"gdfgd"}',
'{"name":"fdgdfg","amount":"dfgdf"}',
'{"name":"dfgdfgdf","amount":"gdfgdf"}'
],
'directions': [
'{"content":"gdfgfd"}',
'{"content":"gdfgdfg"}',
'{"content":"dfgdfdfg"}'
],
'image': [
<InMemoryUploadedFile: luisana-zerpa-MJPr6nOdppw-unsplash.jpg (image/jpeg)>
]
}>
序列化程式.py
class IngredientSerializer(serializers.ModelSerializer):
class Meta:
model = Ingredient
fields = ('name', 'amount')
class DirectionSerializer(serializers.ModelSerializer):
class Meta:
model = Direction
fields = ('content',)
class RecipeSerializer(serializers.ModelSerializer):
owner = serializers.StringRelatedField()
ingredients = IngredientSerializer(many=True, read_only=False)
directions = DirectionSerializer(many=True, read_only=False)
class Meta:
model = Recipe
fields = (
'id',
'name',
'owner',
'image',
'description',
'created_at',
'ingredients',
'directions',
)
def create(self, validated_data):
print (validated_data) <----See Below
has_ingredients = validated_data.get("ingredients")
has_directions = validated_data.get("directions")
if has_ingredients:
ingredient_data = validated_data.pop('ingredients')
if has_directions:
direction_data = validated_data.pop('directions')
recipe_name = validated_data.get('name')
recipe_name = recipe_name.replace('"','')
recipe_description = validated_data.get('description')
recipe_description = recipe_description.replace('"','')
recipe = Recipe.objects.create(name=recipe_name, description=recipe_description, image=validated_data.get('image'))
if has_ingredients:
for ingredient in ingredient_data:
Ingredient.objects.create(recipe=recipe, name=ingredient.get("name"), amount=ingredient.get("amount"))
if has_directions:
for direction in direction_data:
Direction.objects.create(recipe=recipe, content=direction.get("content"))
return recipe
驗證 資料注意:如果我為成分和方向添加“required = False”,我只能得到這個,否則它只會回傳 404err
{
'name': '"fdgdfgdf"',
'image': <InMemoryUploadedFile: luisana-zerpa-MJPr6nOdppw-unsplash.jpg (image/jpeg)>,
'description': '"gfdgdfg"'
}
我嘗試研究覆寫序列化程式上的 .is_valid() 方法,但在官方檔案中找不到任何內容。如果我使用 Postman 應用程式發布資料,那么一切正常,但是每當我從前端發送資料時,就會發生這種情況。我想知道我是否與我如何發送資料有關,但我不想包含太多不必要的內容。
在此先感謝您的幫助:)
uj5u.com熱心網友回復:
我相信您忘記將配料和說明發送到新配方實體。
這就是為什么您的 POST 端點僅在不需要時才起作用的原因
您可以在創建成分實體后創建與配方的關系
ingredient = Ingredient.objects.create(**inputs)
recipe.ingredient = ingredient
recipe.save()
方向也是如此:
direction = Direction.objects.create(**inputs)
recipe.direction = direction
recipe.save()
它們已經在 IngredientSerializer 和 DirectionSerializer 中得到驗證,因此您可以安全地創建與 Recipe 的關系
快速提示:如果你有一個名為has_ingredients的標志,你可能意味著你可以有沒有成分的食譜,在這種情況下,該欄位應該是required=False
如果您需要所需的成分和說明檔案,則需要使用所有輸入創建配方,例如:
recipe = Recipe.objects.create(
name=recipe_name,
description=recipe_description,
image=validated_data.get('image'),
ingredient=ingredient,
direction=direction
)
另一種方法:您可以先創建一個帶有一些欄位的 Recipe 實體,然后添加成分和方向,最后呼叫 .save() 來注冊新的資料庫條目。
uj5u.com熱心網友回復:
我已經找到答案了!
一直以來的問題在于我如何發布資料。
最初我正在發送“成分”和“這樣的方向”的帖子資料......
ingredients.forEach((ingredient) => {
formData.append('ingredients',{
'name':ingredients.name,
'amount':ingredient.amount
});
});
我也有一個用于“方向”的 forEach 回圈,它幾乎遵循相同的模式。
使用 multipart/form-data 發布物件串列的正確方法應該是這樣的
ingredients.forEach((ingredient, index) => {
formData.append(`ingredients[${index}]name`, JSON.stringify(ingredient.name));
formData.append(`ingredients[${index}]amount`, JSON.stringify(ingredient.amount))
});
不同之處在于,在發布串列時,我們必須詳細說明串列中每個專案的確切路徑。
例如formData.append( ingredients[${index}]name, JSON.stringify(ingredient.name));
這就是我所知道的一切,如果有人有更多關于我們需要做什么的資訊,請補充,因為沒有太多關于為什么會這樣的資訊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/517401.html
標籤:djangohttp邮政django-rest-framework
上一篇:按一定順序執行執行緒
