微信公众号:萝卜大杂烩 关注可了解更多的原创内容。问题或建议,请公众号留言或加本人微信; 如果你觉得文章对你有帮助,欢迎加微信交流
今天继续分享 Vue 系列,提交多对多表单
首先有一个简单的表单,一个必填的输入框,一个 textarea 类型输入框,还有两个多选的下拉框 页面效果如下:
再来看看表结构是怎样的 这里主要用到了三张表:
另外其实还有 User 和 Testsuit 表,但是在本例子中并不涉及
Project 表:
class Project(db.Model):
__tablename__ = 'projects'
id = db.Column(db.Integer, primary_key=True)
create_time = db.Column(db.Date)
projectname = db.Column(db.String(64), unique=True, index=True)
description = db.Column(db.Text)
Rel_Testsuit_Project 表
class Rel_Testsuit_Project(db.Model):
__tablename__ = 'rel_testsuit_project'
id = db.Column(db.Integer, primary_key=True)
testsuit_id = db.Column(db.Integer)
project_id = db.Column(db.Integer)
Rel_User_Project 表
class Rel_User_Project(db.Model):
__tablename__ = 'rel_user_project'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer)
project_id = db.Column(db.Integer)
再来看看页面布局的代码 在新创建的 .vue 文件中,添加布局代码
<el-dialog title="新增项目" :visible.sync="dialogFormVisible">
<el-form :model="form" ref="form">
<el-form-item label="项目名称" :label-width="formLabelWidth" prop="projectname"
:rules="[{required: true, message: '项目名称不能为空', trigger: 'change'}]">
<el-input v-model="form.projectname" placeholder="输入项目名称">
</el-input>
</el-form-item>
<el-form-item label="项目描述" :label-width="formLabelWidth">
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 8}" v-model="form.description" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="测试集" :label-width="formLabelWidth" prop="suitname">
<el-select v-model="form.suitname" multiple placeholder="请选择测试集" v-on:focus="getSuit()">
<el-option
v-for="item in suits"
:key="item.value"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="人员" :label-width="formLabelWidth" prop="username">
<el-select v-model="form.username" multiple placeholder="请添加人员" v-on:focus="getUser()">
<el-option
v-for="item in userSelection"
:key="item.value"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" :loading="loginLoading" @click="save('form'), resetForm('form')">确 定</el-button>
</div>
</el-dialog>
在对话框中定义了 :visible.sync="dialogFormVisible",当点击某个按钮,比如:添加,则设置 dialogFormVisible = true,那么该对话框就会展示在页面上了。 其中函数 getSuit 和 getUser 分别从后台回去数据,展示在下拉框中。
下面是脚本代码部分
<script>
import ToolBar from '~/components/ToolBar/ToolBar.vue';
import HelpHint from '~/components/HelpHint/HelpHint.vue';
import projectdata from '../../api/testproject.js';
import suitdata from '../../api/testsuit.js';
import dealdata from '../../api/data.js';
export default {
data() {
return {
formLabelWidth: '120px',
loginLoading: false,
dialogFormVisible: false,
userSelection: [],
form: {
id: '',
projectname: '',
suitname: [],
description: '',
username: [],
},
projects: [],
suits: [],
users: [],
searchParams:{
projectName:'',
postType:'',
projectStatus:'published',
},
}
},
methods: {
resetForm(formName){
this.$refs[formName].resetFields();
},
getProject(){
let APP = this;
let projectName = this.searchParams.projectName;
let projectStatus = this.searchParams.projectStatus;
let parm = {projectName: projectName, projectStatus:projectStatus};
projectdata.getProject(APP, parm);
},
getSuit(){
let APP = this;
suitdata.getSuit(APP);
},
getUser(){
let APP = this;
dealdata.getuser()
.then(res => {
if(res.data.code == 200) {
APP.userSelection = res.data.selection_data;
//console.log(APP.projects);
//console.log(APP.userSelection);
}
})
.catch(function(error){
APP.$message.error("网络错误");
})
},
save(formName){
let APP = this;
this.$refs[formName].validate((valid) => {
var projectname = this.form['projectname'];
var description = this.form['description'];
var suitname = this.form['suitname'];
var username = this.form['username'];
if(valid) {
var data = {
projectname: projectname, description: description,
suitname: suitname, username: username
};
//console.log(data);
APP.loginLoading = true;
dealdata.saveproject(data)
.then(res => {
if(res.data.code == 200){
APP.loginLoading = false;
APP.dialogFormVisible = false;
this.$message.success(res.data.message);
} else{
APP.loginLoading = false;
this.$message.error(res.data.message);
}
projectdata.getProject(APP);
})
.catch(function(error) {
APP.loginLoading = false;
console.log(APP.$message.error("网络错误"));
})
}else{
APP.loginLoading = false;
console.log("error save");
if(projectname == ''){
this.$message.error('项目名称不能为空');
return false;
};
}
})
},
},
mounted(){
this.getProject();
},
components: {
ToolBar,HelpHint
}
}
</script>
这里我们只关心 save 函数,组装 data 数据,通过 post 方法提交到后台。同时我们也可以看到,初始阶段,dialogFormVisible 是设置为 false 的。
下面我们来看看后台的 API,还是先给出完整的代码。
class ProjectAddView(Resource):
def post(self):
try:
projectinfo = request.get_json()
print(projectinfo)
if 'projectname' in projectinfo:
projectname = request.get_json()['projectname']
else:
return {'code': 422, 'message': '请输入名称'}
if 'description' in projectinfo:
description = request.get_json()['description']
else:
description = ''
if 'suitname' in projectinfo:
suitname = request.get_json()['suitname']
else:
suitname = ''
if 'username' in projectinfo:
username = request.get_json()['username']
else:
username = ''
ptname = Project.query.filter_by(projectname=projectname).first()
if ptname:
return {'code': 422, 'message': "该项目已经存在"}
else:
c_time = datetime.date.today()
project = Project(projectname=projectname, description=description, create_time=c_time)
db.session.add(project)
db.session.commit()
projectid = Project.query.filter_by(projectname=projectname).first().id
if len(suitname) != 0:
for ts in suitname:
suitid = TestSuit.query.filter_by(testsuitname=ts).first().id
r_ts_pt = Rel_Testsuit_Project(testsuit_id=suitid, project_id=projectid)
db.session.add(r_ts_pt)
db.session.commit()
if len(username) != 0:
for u in username:
userid = User.query.filter_by(username=u).first().id
r_us_pt = Rel_User_Project(user_id=userid, project_id=projectid)
db.session.add(r_us_pt)
db.session.commit()
return {'code': 200, 'message': 'Project创建成功'}
except:
raise
最主要的部分,就是判断 suitname 和 username,因为这两个变量从前端传过来时都是列表形式的,所以只要判断下其长度是否为0,就能判断出提交表单时,是否选择了这两个选项,如果长度不为0,则循环这两个列表,并分别取出对应表中的 ID 值,保存至中间表中。
这样,就完成了多对多的绑定操作。
猜泥稀饭: