美文网首页刘悦的技术博客
使用Python3.7+Django2.0.4配合vue.js2

使用Python3.7+Django2.0.4配合vue.js2

作者: 刘悦的技术博客 | 来源:发表于2020-07-07 13:10 被阅读0次

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_133

    所谓的无限极分类是啥?其实简单点说就是一个人类可以繁衍出多个后代,然后一个后代又可以分另外多个后代这样无限繁衍下去(可以想象神奇动物在哪里2里面莱斯特兰奇的家族族谱),就好象linux系统你可以新建一个文件夹,然后在这个文件夹里又可以建一些个文件夹,在文件夹底下还可以建一些文件夹一样,随后使用tree命令就可以查看文件夹目录层级。

    那么这种层级结构也成为树结构在日常的开发需求里也是很常见的,比如美多商城系统的商品分类,课程的目录章节,以及以及论坛里的帖子回复等等,本次我们后台利用Django来写一个能够返回层级结构数据的接口,接口将该数据以json的形式返回前端,前端使用vue的组件递归来展示数据。

    首先,打开django项目中的models.py,新建一个类别的模型类,这里我们以最简单的parentid的形式来建立

    class Cate(models.Model):
    
        #主键 通过参数声明主键
        id = models.AutoField(primary\_key=True)
        #分类名称
        name = models.CharField(max\_length=500)
        #父级id
        pid = models.IntegerField()
    
        #表名
        class Meta:
            db\_table = 'cate'
    

    由于我们的项目基于drf框架,所以要增加一个序列器类,如果你的项目没有用drf,可以直接用json模块来进行序列化

    from rest\_framework import serializers
    from myapp.models import Cate
    
    
    class CateSer(serializers.ModelSerializer):
        class Meta:
            model = Cate
            fields = "\_\_all\_\_"
    

    由于django序列化出来的类不具备层级结构,所以我们提前写好一个用来递归的方法:

    def xTree(datas):
        lists=\[\]
        tree={}
        parent\_id=''
        for i in datas:
            item=i
            tree\[item\['id'\]\]=item
        root=None
        for i in datas:
            obj=i
            if not obj\['pid'\]:
                root=tree\[obj\['id'\]\]
                lists.append(root)
            else:
                parent\_id=obj\['pid'\]
                if 'childlist' not in tree\[parent\_id\]:   
                    tree\[parent\_id\]\['childlist'\]=\[\]
                tree\[parent\_id\]\['childlist'\].append(tree\[obj\['id'\]\])
        return lists
    

    此时我们写一个视图接口,用来从数据库中读取数据

    class MyTree(APIView):
        def get(self,request):
    
    
            #获取订单列表
            catelist = Cate.objects.filter()
            #序列化
            catelist\_ser = CateSer(catelist,many=True)
    
            mylist= xTree(catelist\_ser.data)
    
    
            return Response(mylist)
    

    请在mysql库里存一些测试数据

    image

    测试一下接口,看看是否以json的形式返回了层级结构

    image

    ok,接口没有问题,现在我们把目光投向前端,打开vue项目,新建一个Reply.vue组件

    所谓递归组件: 就是组件可以在它们自己的模板中调用自身,不过它们只能通过 name 选项来做这件事,例如给组件设置属性 name: 'Reply',然后在模板中就可以使用 Reply 调用自己进行递归调用了

    <template>
    
        <div>
    
                <li >
                        <div :class="\[data.id==0 ? 'root': '', 'reply'\]">{{ data.name }}</div>
                
                        <ul v-if="data.childlist && data.childlist.length>0">
                            <Reply v-for="child in data.childlist" :key="child.id" :data="child"/>
                        </ul>
                    </li>
    
            </div>
    </template>
        
        <script>
        export default {
            name: 'Reply', // 递归组件需要设置 name 属性,才能在模板中调用自己
            props:\['data'\],
        };
        </script>
        
        <style >
        .reply {
            padding-left: 4px;
            border-left: 1px solid #eee;
        }
    
        ul {
                padding-left: 20px;
                list-style: none;
            }
    
            .root { display: none; }
    
        
    
        </style>
    
    
    

    然后在其他任意组件中调用该Reply.vue组件,传入刚刚写好的接口数据

    <template>
            <div>
                    
                    <Reply :data="data" />
        
            </div>
        </template>
           
          <script>
        
            import {config,formatXml} from '../config.js';
            import mh\_test from './mh\_test.vue';
            import Reply from './Reply.vue';
        
            import md5 from 'js-md5';
        
        
          export default {
            data () {
              return {
                  data:{},
                online: 0
              }
            },
            components: {
                //'mh\_test':mh\_test
                Reply
          },
        
            //钩子方法
            mounted:function(){
                
                    this.get\_token();
            },
            //绑定事件
            methods:{
        
                get\_token(){
        
                 this.axios.get('http://localhost:8000/mytree/').then((result) =>{
                console.log(result);
                var mytree = {'id':0,name:'123'};
                mytree\['childlist'\] = result.data;
                this.data = mytree;
    
    
                console.log(this.data);
    
                });
    
                },
           
        
            }
          }
          </script>
           
        <style>
        
        .on {
                    background: #cdcbff;
                }
        .off {
            background: #fefdff;
        
        }
        
        </style>
    

    最后请求页面,可以看到展示的效果:

    image

    当然了,vue组件也可以间接的调用自己实现递归,这涉及到组件之间的循环引用,这样比较麻烦,可读性也间接的降低了不少。

    原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_133

    相关文章

      网友评论

        本文标题:使用Python3.7+Django2.0.4配合vue.js2

        本文链接:https://www.haomeiwen.com/subject/llyaqktx.html