经典前端+后端+表头+表身的开发实战参考简易模板【珍藏】
前端部分(Vue 3 + Element Plus)
1. 修改 MPS002HList.vue
(主生产计划列表)
a. 添加查询表单
在模板中添加查询表单,包含产品料号、品名、规格和年月的输入项。
<template> <div> <!-- 查询表单 --> <el-form :inline="true" :model="filters" class="demo-form-inline"> <el-form-item label="产品料号"> <el-input v-model="filters.bo_no" placeholder="请输入产品料号"></el-input> </el-form-item> <el-form-item label="品名"> <el-input v-model="filters.item_name" placeholder="请输入品名"></el-input> </el-form-item> <el-form-item label="规格"> <el-input v-model="filters.item_spec" placeholder="请输入规格"></el-input> </el-form-item> <el-form-item label="年月"> <el-date-picker v-model="filters.mps_ym" type="month" placeholder="选择年月" format="yyyy-MM" value-format="yyyy-MM" /> </el-form-item> <el-form-item> <el-button type="primary" @click="fetchMpsList">查询</el-button> <el-button @click="resetFilters">重置</el-button> </el-form-item> </el-form> <!-- 生产计划列表 --> <el-table :data="mpsList" style="width: 100%" v-loading="loading"> <el-table-column prop="mps_no" label="单号" width="180"> <template #default="{ row }"> <el-button type="text" @click="showMpsDetails(row.mps_no)"> {{ row.mps_no }} </el-button> </template> </el-table-column> <el-table-column prop="mps_date" label="单据时间" width="180" /> <el-table-column prop="fa_no_name" label="厂别" width="180" /> <el-table-column prop="bo_no" label="产品料号" width="180" /> <el-table-column prop="bo_no_name" label="品名" width="180" /> <el-table-column prop="bo_no_spec" label="规格" width="180" /> <el-table-column prop="mps_ym" label="年月" width="100" /> <el-table-column prop="mps_qty" label="数量" width="100" /> </el-table> <!-- 分页 --> <el-pagination v-if="mpsList.length" background :current-page="page" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="handlePageChange" /> <!-- 详情对话框 --> <el-dialog :visible.sync="showDetails" width="80%"> <template #header> <h3>主生产计划详情</h3> </template> <MPS002HDetail :mps_no="selectedMpsNo" /> </el-dialog> </div> </template>
b. 修改脚本部分
在 setup
函数中,添加 filters
数据,并修改 fetchMpsList
函数以包含查询参数。
<script> import { ref, onMounted } from 'vue'; import { getMPS002 } from '@/api/mpsApp/MPS002HModel'; import MPS002HDetail from './MPS002HDetail.vue'; export default { components: { MPS002HDetail }, setup() { const mpsList = ref([]); const page = ref(1); const pageSize = ref(10); const total = ref(0); const loading = ref(false); const showDetails = ref(false); const selectedMpsNo = ref(null); const filters = ref({ bo_no: '', item_name: '', item_spec: '', mps_ym: '', }); const fetchMpsList = async () => { loading.value = true; try { const params = { page: page.value, page_size: pageSize.value, bo_no: filters.value.bo_no, item_name: filters.value.item_name, item_spec: filters.value.item_spec, mps_ym: filters.value.mps_ym, }; const response = await getMPS002(params); mpsList.value = response.data.results; total.value = response.data.count; } catch (error) { console.error('Error fetching MPS002 list:', error); } finally { loading.value = false; } }; const resetFilters = () => { filters.value = { bo_no: '', item_name: '', item_spec: '', mps_ym: '', }; fetchMpsList(); }; const showMpsDetails = (mps_no) => { selectedMpsNo.value = mps_no; showDetails.value = true; }; const handlePageChange = (newPage) => { page.value = newPage; fetchMpsList(); }; onMounted(fetchMpsList); return { mpsList, page, pageSize, total, loading, showDetails, selectedMpsNo, filters, fetchMpsList, resetFilters, showMpsDetails, handlePageChange, }; }, }; </script>
2. 修改 MPS002D1List.vue
(物料需求明细列表)
a. 添加查询表单
<template> <div> <!-- 查询表单 --> <el-form :inline="true" :model="filters" class="demo-form-inline"> <el-form-item label="料号"> <el-input v-model="filters.item_no" placeholder="请输入料号"></el-input> </el-form-item> <el-form-item label="品名"> <el-input v-model="filters.item_name" placeholder="请输入品名"></el-input> </el-form-item> <el-form-item label="规格"> <el-input v-model="filters.item_spec" placeholder="请输入规格"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="fetchMpsD1List">查询</el-button> <el-button @click="resetFilters">重置</el-button> </el-form-item> </el-form> <!-- 物料需求明细列表 --> <el-table :data="mpsD1List" style="width: 100%" v-loading="loading"> <el-table-column prop="item_no" label="料号" width="180" /> <el-table-column prop="item_name" label="品名" width="180" /> <el-table-column prop="item_spec" label="规格" width="180" /> <el-table-column prop="item_qty" label="需求数量" width="180" /> <!-- 添加更多列 --> </el-table> <!-- 分页 --> <el-pagination v-if="mpsD1List.length" background :current-page="page" :page-size="pageSize" layout="total, prev, pager, next" :total="total" @current-change="handlePageChange" /> </div> </template>
b. 修改脚本部分
<script> import { ref, onMounted } from 'vue'; import { getMPS002D1 } from '@/api/mpsApp/MPS002D1Model'; export default { setup() { const mpsD1List = ref([]); const page = ref(1); const pageSize = ref(10); const total = ref(0); const loading = ref(false); const filters = ref({ item_no: '', item_name: '', item_spec: '', }); const fetchMpsD1List = async () => { loading.value = true; try { const params = { page: page.value, page_size: pageSize.value, item_no: filters.value.item_no, item_name: filters.value.item_name, item_spec: filters.value.item_spec, }; const response = await getMPS002D1(params); mpsD1List.value = response.data.results; total.value = response.data.count; } catch (error) { console.error('Error fetching MPS002D1 list:', error); } finally { loading.value = false; } }; const resetFilters = () => { filters.value = { item_no: '', item_name: '', item_spec: '', }; fetchMpsD1List(); }; const handlePageChange = (newPage) => { page.value = newPage; fetchMpsD1List(); }; onMounted(fetchMpsD1List); return { mpsD1List, page, pageSize, total, loading, filters, fetchMpsD1List, resetFilters, handlePageChange, }; }, }; </script>
后端部分(Django REST Framework)
为了支持前端的查询功能,需要在后端的视图中添加筛选功能。
1. 修改 MPS002HModel
的视图
from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend from .models import MPS002HModel from .serializers import MPS002HSerializer class MPS002HViewSet(viewsets.ModelViewSet): queryset = MPS002HModel.objects.all().order_by('-mps_date') serializer_class = MPS002HSerializer filter_backends = [DjangoFilterBackend, filters.SearchFilter] filterset_fields = ['mps_ym'] search_fields = ['bo_no__item_no', 'bo_no__item_name', 'bo_no__item_spec']
说明
- filter_backends:使用
DjangoFilterBackend
和SearchFilter
,可以实现精确过滤和模糊搜索。 - filterset_fields:精确过滤的字段,这里包括
mps_ym
。 - search_fields:模糊搜索的字段,包括关联的
bo_no
(产品料号)的item_no
、item_name
、item_spec
。
2. 修改 MPS002D1Model
的视图
from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend from .models import MPS002D1Model from .serializers import MPS002D1Serializer class MPS002D1ViewSet(viewsets.ModelViewSet): queryset = MPS002D1Model.objects.all() serializer_class = MPS002D1Serializer filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ['item_no__item_no', 'item_no__item_name', 'item_no__item_spec']
说明
- search_fields:对于物料需求明细,可以根据
item_no
(料号)、item_name
(品名)、item_spec
(规格)进行模糊搜索。
3. 安装和配置 django-filter
如果还没有安装 django-filter
,需要先安装:
pip install django-filter
并在 settings.py
中添加:
REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] }
更新序列化器
确保您的序列化器包含必要的字段,以便前端能够正确接收数据。
MPS002HSerializer
from rest_framework import serializers from .models import MPS002HModel class MPS002HSerializer(serializers.ModelSerializer): fa_no_name = serializers.CharField(source='fa_no.fa_name', read_only=True) bo_no_name = serializers.CharField(source='bo_no.item_name', read_only=True) bo_no_spec = serializers.CharField(source='bo_no.item_spec', read_only=True) bo_no = serializers.CharField(source='bo_no.item_no', read_only=True) class Meta: model = MPS002HModel fields = ['id', 'mps_no', 'mps_date', 'fa_no', 'fa_no_name', 'bo_no', 'bo_no_name', 'bo_no_spec', 'mps_ym', 'mps_qty']
MPS002D1Serializer
from rest_framework import serializers from .models import MPS002D1Model class MPS002D1Serializer(serializers.ModelSerializer): item_name = serializers.CharField(source='item_no.item_name', read_only=True) item_spec = serializers.CharField(source='item_no.item_spec', read_only=True) item_no = serializers.CharField(source='item_no.item_no', read_only=True) class Meta: model = MPS002D1Model fields = ['id', 'mps_no', 'item_no', 'item_name', 'item_spec', 'item_qty', 'rmk']
更新 API 请求
1. 更新前端 API 调用
在您的 API 请求文件中,确保查询参数能够正确传递。
MPS002HModel
API
import request from '@/utils/request'; const baseUrl = '/mpsApp/MPS002HModel/'; export function getMPS002(params) { return request({ url: baseUrl, method: 'get', params, }); }
MPS002D1Model
API
import request from '@/utils/request'; const baseUrl = '/mpsApp/MPS002D1Model/'; export function getMPS002D1(params) { return request({ url: baseUrl, method: 'get', params, }); }
总结
通过上述步骤,我们实现了:
-
前端:在
MPS002HModel
和MPS002D1Model
的列表页面中添加了查询表单,可以根据指定的字段进行筛选,并将查询条件传递给后端。 -
后端:在 Django REST Framework 的视图中,使用
django-filter
和SearchFilter
实现了对指定字段的精确过滤和模糊搜索。 -
序列化器:更新了序列化器,以便在返回数据时包含关联字段的信息,如品名和规格。
-
API 请求:确保查询参数能够正确地通过前端 API 请求发送到后端。
这样,用户就可以在前端界面上根据产品料号、品名、规格和年月对主生产计划列表进行查询,也可以在物料需求明细列表中根据料号、品名、规格进行筛选。