前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue + Flask 小知识(四)

Vue + Flask 小知识(四)

作者头像
周萝卜
发布2019-07-30 15:10:06
7160
发布2019-07-30 15:10:06
举报
文章被收录于专栏:萝卜大杂烩

微信公众号:萝卜大杂烩 关注可了解更多的原创内容。问题或建议,请公众号留言或加本人微信; 如果你觉得文章对你有帮助,欢迎加微信交流

今天继续分享 Vue 系列,提交多对多表单

页面布局

首先有一个简单的表单,一个必填的输入框,一个 textarea 类型输入框,还有两个多选的下拉框 页面效果如下:

表结构

再来看看表结构是怎样的 这里主要用到了三张表:

  1. Project 表,存储项目信息
  2. Rel_Testsuit_Project 表,测试集和项目的关系表
  3. Rel_User_Project 表,用户和项目的关系表

另外其实还有 User 和 Testsuit 表,但是在本例子中并不涉及

Project 表:

代码语言:javascript
复制
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 表

代码语言:javascript
复制
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 表

代码语言:javascript
复制
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 代码

再来看看页面布局的代码 在新创建的 .vue 文件中,添加布局代码

代码语言:javascript
复制
<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 分别从后台回去数据,展示在下拉框中。

下面是脚本代码部分

代码语言:javascript
复制
<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 代码

下面我们来看看后台的 API,还是先给出完整的代码。

代码语言:javascript
复制
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 值,保存至中间表中。

这样,就完成了多对多的绑定操作。


猜泥稀饭:

Vue + Flask 实现单页面应用

Vue + Flask 小知识(一)

Vue + Flask 小知识(二)

Vue + Flask 小知识(三)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萝卜大杂烩 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 页面布局
  • 表结构
  • Vue 代码
  • API 代码
  • Vue + Flask 实现单页面应用
  • Vue + Flask 小知识(一)
  • Vue + Flask 小知识(二)
  • Vue + Flask 小知识(三)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档