You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Django REST Framework中“Lists are not currently supported in HTML input”错误?

解决DRF嵌套序列化器HTML表单不支持列表的问题

问题原因

DRF默认的HTML表单渲染器无法处理many=True的嵌套序列化器字段,因此会抛出"Links: Lists are not currently supported in HTML input."的错误。以下是两种可行的解决方式:


方式一:使用JSON格式提交数据

这是最直接的解决方案,符合你提到的通过JSON处理嵌套序列化器的需求:

  1. 在DRF自带的API测试界面中,切换到Raw data标签页
  2. 将请求格式选择为JSON,然后按照以下结构输入数据:
    {
      "firstname": "你的名字",
      "lastname": "你的姓氏",
      "links": [
        {"linkname": "GitHub", "linkurl": "https://github.com"},
        {"linkname": "个人网站", "linkurl": "https://example.com"}
      ]
    }
    
  3. 点击发送即可完成提交

如果是前端代码调用API,只需将请求的Content-Type设置为application/json,并将上述JSON作为请求体发送即可。


方式二:自定义HTML表单与视图处理(保留HTML提交)

如果需要通过传统HTML表单提交,可以通过动态添加字段+视图手动解析的方式实现:

1. 修改视图代码

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Work, Link
from .serializers import WorkSerializer

class WorkCreateAPIView(APIView):
    def post(self, request):
        # 创建Work主对象
        work = Work.objects.create(
            firstname=request.data.get("firstname"),
            lastname=request.data.get("lastname")
        )
        
        # 批量处理关联的Link数据
        link_names = request.data.getlist("linkname[]")
        link_urls = request.data.getlist("linkurl[]")
        
        for name, url in zip(link_names, link_urls):
            if name.strip() and url.strip():
                Link.objects.create(
                    links=work,
                    linkname=name,
                    linkurl=url
                )
        
        # 序列化并返回结果
        serializer = WorkSerializer(work)
        return Response(serializer.data)

2. 前端HTML表单示例

<form method="post" action="/api/work/create/">
    {% csrf_token %}
    <div>
        <label>Имя:</label>
        <input type="text" name="firstname" placeholder="Введите имя">
    </div>
    <div>
        <label>Фамилия:</label>
        <input type="text" name="lastname" placeholder="Введите фамилию">
    </div>
    <div id="links-container">
        <div class="link-row">
            <label>Название ссылки:</label>
            <input type="text" name="linkname[]" placeholder="Например: GitHub">
            <label>URL:</label>
            <input type="text" name="linkurl[]" placeholder="Например: https://github.com">
        </div>
    </div>
    <button type="button" onclick="addLinkRow()">Добавить еще ссылку</button>
    <button type="submit">Сохранить</button>
</form>

<script>
function addLinkRow() {
    const container = document.getElementById("links-container");
    const row = document.createElement("div");
    row.className = "link-row";
    row.innerHTML = `
        <label>Название ссылки:</label>
        <input type="text" name="linkname[]" placeholder="Например: GitHub">
        <label>URL:</label>
        <input type="text" name="linkurl[]" placeholder="Например: https://github.com">
    `;
    container.appendChild(row);
}
</script>

额外优化建议

你的Link模型中外键字段命名为links容易造成混淆,建议修改为语义更清晰的work:

class Link(models.Model):
    work = models.ForeignKey(Work, related_name='links', on_delete=models.CASCADE, blank=True)
    linkname = models.CharField("linkname", max_length=100, blank=True)
    linkurl = models.CharField("linkurl", max_length=100, blank=True)

内容的提问来源于stack exchange,提问作者Елена М

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:47:53