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

DRF 如何获取外键可选值填充前端表单的下拉选择框

实现方案

第一步:后端新增品种列表接口

你需要先给Breed模型加只读接口,返回所有可选品种的id和名称,修改代码如下:

新增Breed序列化器

class BreedSerializer(serializers.ModelSerializer):
    class Meta:
        model = Breed
        # 假设Breed模型中用name字段存储品种的显示名称,可根据实际字段调整
        fields = ['id', 'name']

新增Breed只读视图集

# 继承ReadOnlyModelViewSet,仅提供列表、详情两个只读接口,不需要增删改权限
class BreedViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Breed.objects.all()
    serializer_class = BreedSerializer

注册接口路由

在项目的urls.py中注册该视图集的路由:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'pets', PetViewSet)
router.register(r'breeds', BreedViewSet) # 新增品种接口路由

urlpatterns = [
    path('', include(router.urls)),
]

配置完成后,访问/breeds/接口即可获得所有品种的列表数据,返回格式示例:

[{"id":1,"name":"Breed1"},{"id":2,"name":"Breed2"},{"id":3,"name":"Breed3"}]

小提醒:你当前贴出的PetSerializer代码中fields = "__all__缺少闭合双引号,需要修改为fields = "__all__"才能正常运行。

第二步:前端实现下拉框填充

原生JS+Ajax实现

页面加载时请求品种接口,动态生成option插入下拉框即可:

document.addEventListener('DOMContentLoaded', function() {
  const breedSelect = document.getElementById('breeds');
  // 请求品种列表接口
  fetch('/breeds/')
    .then(res => res.json())
    .then(breedList => {
      breedList.forEach(breed => {
        const option = document.createElement('option');
        option.value = breed.id;
        option.textContent = breed.name;
        breedSelect.appendChild(option);
      })
    })
    .catch(err => console.error('品种列表获取失败:', err));
});

React实现

在组件挂载时请求数据,渲染下拉选项:

import { useState, useEffect } from 'react';

export default function PetForm() {
  const [breedList, setBreedList] = useState([]);
  const [formData, setFormData] = useState({ name: '', breed: '' });

  // 组件挂载时拉取品种列表
  useEffect(() => {
    fetch('/breeds/')
      .then(res => res.json())
      .then(data => setBreedList(data))
      .catch(err => console.error('品种列表获取失败:', err));
  }, []);

  const handleChange = (e) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // 提交表单到宠物接口的逻辑
    fetch('/pets/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(formData)
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">名称</label><br />
      <input 
        type="text" 
        id="name" 
        name="name" 
        value={formData.name} 
        onChange={handleChange} 
      /><br />
      <label htmlFor="breeds">选择品种</label>
      <select 
        name="breed" 
        id="breeds" 
        value={formData.breed} 
        onChange={handleChange}
      >
        <option value="">请选择品种</option>
        {breedList.map(breed => (
          <option key={breed.id} value={breed.id}>{breed.name}</option>
        ))}
      </select>
      <button type="submit">提交</button>
    </form>
  );
}

内容的提问来源于stack exchange,提问作者Santhosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:54:05