如何将Django的Choices、外键数据传递到Vue 3并复用同个API接口
实现方案:无需单独请求每个字段,可在同一接口返回所有下拉选项
你完全不用为每个字段单独发起API请求,只需要在现有Django接口的返回结果中追加对应字段的选项元数据即可,两种常用实现方式如下:
方式1:和业务数据接口合并返回
如果你的Vue页面本身就需要请求图书相关的业务数据(比如图书列表、图书详情),直接在该接口的返回结果中附加所有下拉选项即可,示例代码(基于Django REST Framework):
from rest_framework.response import Response from rest_framework import viewsets from django_countries import countries from .models import Book, BOOK_COVER_CHOICES, Author from .serializers import BookSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 重写列表返回逻辑,追加选项元数据 def list(self, request, *args, **kwargs): # 先拿到原有的业务数据 response = super().list(request, *args, **kwargs) # 追加所有下拉框的选项数据 response.data['meta_options'] = { 'country': list(countries), # django-countries自带的国家选项列表 'authors': Author.objects.values('id', 'name'), # 外键关联的作者选项 'cover': BOOK_COVER_CHOICES # 模型中定义的封面枚举选项 } return response
Vue 3侧直接从接口返回结果中拿选项渲染即可,无需额外请求:
<script setup> import { ref, onMounted } from 'vue' import axios from 'axios' const bookList = ref([]) const formOptions = ref({}) const form = ref({ country: '', author: '', cover: '' }) onMounted(async () => { const res = await axios.get('/api/books/') bookList.value = res.data.results // 一次拿到所有下拉选项 formOptions.value = res.data.meta_options }) </script> <template> <!-- 国家下拉框 --> <select v-model="form.country"> <option v-for="[code, name] in formOptions.country" :key="code" :value="code" > {{ name }} </option> </select> <!-- 作者下拉框 --> <select v-model="form.author"> <option v-for="author in formOptions.authors" :key="author.id" :value="author.id" > {{ author.name }} </option> </select> <!-- 封面下拉框 --> <select v-model="form.cover"> <option v-for="[value, label] in formOptions.cover" :key="value" :value="value" > {{ label }} </option> </select> </template>
方式2:单独写轻量接口返回所有表单选项
如果是纯新增图书的表单页面,不需要提前请求图书业务数据,你可以单独写一个轻量接口一次性返回所有表单所需的选项,也只需要发起1次请求,远好于每个字段单独请求:
from rest_framework.views import APIView from rest_framework.response import Response from django_countries import countries from .models import BOOK_COVER_CHOICES, Author class BookFormOptionsView(APIView): def get(self, request): return Response({ 'country': list(countries), 'authors': Author.objects.values('id', 'name'), 'cover': BOOK_COVER_CHOICES })
然后Vue侧只需要在页面初始化的时候请求一次这个接口即可。
内容的提问来源于stack exchange,提问作者Zhivko Zaikov
相关产品推荐
相关产品推荐

