使用Django REST Framework API通过HTML表单提交时遇类型错误求助
解决HTML表单向Django REST Framework API提交数据的类型错误
错误根源
你碰到的Incorrect type. Expected pk value, received str错误,核心问题是外键字段提交了文本值(比如关联模型的名称),但API要求传入该关联模型的主键ID(数字类型)。
具体解决步骤
1. 修正HTML表单的外键选项值
确保表单里的选择控件(如下拉框)value属性设为关联模型的主键ID,而非名称:
<!-- 错误写法:value是分类名称 --> <select name="category"> <option value="技术">技术</option> <option value="生活">生活</option> </select> <!-- 正确写法:value是分类的主键ID --> <select name="category"> <option value="1">技术</option> <option value="2">生活</option> </select>
如果是用Django模板渲染,直接取模型的id字段即可:
<select name="category"> {% for cate in category_list %} <option value="{{ cate.id }}">{{ cate.name }}</option> {% endfor %} </select>
2. 调整DRF序列化器配置(可选)
如果想让API支持接收名称而非主键ID,修改序列化器为SlugRelatedField:
# serializers.py from rest_framework import serializers from .models import Post, Category class PostSerializer(serializers.ModelSerializer): category = serializers.SlugRelatedField( queryset=Category.objects.all(), slug_field='name' # 对应Category模型中作为标识的唯一字段 ) class Meta: model = Post fields = ['title', 'content', 'category']
注意:slug_field对应的字段必须在数据库中设置为唯一(比如给Category的name字段加unique=True)。
3. 确认表单提交的基础配置
表单必须用POST方法,且带上DRF要求的CSRF令牌:
<form method="POST" action="/api/posts/"> {% csrf_token %} <input type="text" name="title" placeholder="标题"> <textarea name="content"></textarea> <select name="category"> {% for cate in category_list %} <option value="{{ cate.id }}">{{ cate.name }}</option> {% endfor %} </select> <button type="submit">提交</button> </form>
4. 调试提交数据
用浏览器开发者工具的Network面板,查看提交的Form Data,确认外键字段的值是数字类型而非字符串:
Form Data:
title: 测试文章
content: 测试内容
category: 1
内容的提问来源于stack exchange,提问作者gowtham
相关产品推荐
相关产品推荐

