zoukankan      html  css  js  c++  java
  • Django-website 程序案例系列-7 创建多对多关系表

    创建多对多关系表:

    方式一:一共三张表其中有一张中间表需要手工建立(建议使用第一种方式自定制程度高)

    class Host(models.Model):
        hostname = models.CharField(max_length=32, db_index=True)
        ip = models.GenericIPAddressField(db_index=True,protocol="ipv4")
        port = models.IntegerField()
        b = models.ForeignKey('Business', to_field='id')  
    
    
    class Application(models.Model):
        name = models.CharField(max_length=32)
    
    
    class HostToApp(models.Model):        #多对多关系的中间表
        hobj = models.ForeignKey(to='Host', to_field='id')
        aobj = models.ForeignKey(to='Application', to_field='id')
    

      

    方式二:一共两张表没有中间表,中间表又django自动生成(默认只能生成3列数据,如果需要更多数据就需要使用方式一来建立多对多关系)

    class Host(models.Model):
        hostname = models.CharField(max_length=32, db_index=True)
        ip = models.GenericIPAddressField(db_index=True,protocol="ipv4")
        port = models.IntegerField()
        b = models.ForeignKey('Business', to_field='id')  
    
    
    class Application(models.Model):
        name = models.CharField(max_length=32)
        r = models.ManyToManyField("Host")   #建立多对多的关系,django自动生成中间表

    #操作第三章表
    obj = Application.objects.get(id=1)
    obj.r.add(1) #增加第三张表的关系
    obj.r.add(2,3)
    obj.r.add(*[1,2,3,4])

    obj.r.remove(1)      #删除
    obj.r.remove(2,3)
    obj.r.remove(*[1,2,3])
      
    obj.r.clear()        #清空
    obj.r.set([3,5,7])     #修改
    obj.r.all() #获取所有相关host对象列表(QuerySet)

      

     views.py

    #传统模式使用GET和POST方式来接收表单数据
    def app(request): if request.method == "GET": app_list = models.Application.objects.all() host_list = models.Host.objects.all() return render(request, 'app.html',{'app_list': app_list, 'host_list': host_list}) elif request.method == "POST": app_name = request.POST.get('app_name') #拿到前端传来的增加app的名字 host_list = request.POST.getlist('host_list')         #拿到前端传来的增加host关联的数据,使用getlist()获取列表 obj = models.Application.objects.create(name=app_name)    #Application表中创建新的appname obj.r.add(*host_list)    #创建第三章表中的关系数据 return redirect('/app')    #刷新页面

    #使用aja来实现表单数据的接收
    def ajax_add_app(request): ret = {'status': True, 'error': None, 'data': None} #设置一个json格式的字符串 app_name = request.POST.get('app_name')          host_list = request.POST.getlist('host_list') obj = models.Application.objects.create(name=app_name) obj.r.add(*host_list)               return HttpResponse(json.dumps(ret))    #返回一个json格式的字符串

      

    HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .host-tag{              #显示主机关系标签的样式
                display: inline-block;
                padding: 3px;
                border: 1px solid red;
                background-color: #0169eb;
            }
            .hide{
                display: none;
            }
            .shade{
                position: fixed;
                top: 0;
                right: 0;
                left: 0;
                bottom: 0;
                background: black;
                opacity: 0.6;
                z-index: 100;
            }
            .add-modal,.edit-modal{
                position: fixed;
                height: 300px;
                 400px;
                top: 100px;
                left: 50%;
                z-index: 101;
                border: 1px solid black;
                background: white;
                margin-left: -200px;
            }
        </style>
    </head>
    <body>
    
        <h1>应用列表</h1>
        <div>
            <input type="button" id="add_host" value="添加"/>
        </div>
        <table border="1">
            <thead>
                <tr>
                    <td>应用名称</td>
                    <td>应用主机列表</td>
                </tr>
            </thead>
            <tbady>
                {% for app in app_list %}            #添加页面中显示Application表的相关信息
                    <tr aid="{{ app.id }}">
                        <td>{{ app.name }}</td>
                        <td>
                            {% for host in app.r.all %}     #通过中间表拿到主机表信息
                                <span class="host-tag" hid="{{ host.id }}">{{ host.hostname }}</span>
                            {% endfor %}
                        </td>
                        <td>
                            <a class="edit">编辑</a>
                        </td>
                    </tr>
                {% endfor %}
            </tbady>
        </table>
        <div class="shade hide"></div>
        <div class="add-modal hide">
            <form action="/app" method="POST" id="add_form">
                <div class="group">
                    <input type="text" id="host" placeholder="应用名称" name="app_name"/>
                </div>
                <div class="group">
                    <select id="host_list" name="host_list" multiple>
                        {% for op in host_list %}      
                            <option value="{{ op.id }}">{{ op.hostname }}</option>  
                        {% endfor %}
                    </select>
                </div>
                <input type="submit" value="提交"/>
                <input type="button" id="cancel" value="取消"/>
                <input type="button" id="add_submit_ajax" value="ajax提交"/>
    
    
            </form>
        </div>
            <div class="edit-modal hide">      #编辑Application表页面(修改)
                <form action="/host" method="POST" id="edit_form" >
                        <input type="text" name="hid" style="display: none;"/>
                        <input type="text"  placeholder="应用名称" name="app"/>
                        <select  name="host_list" multiple>
                            {% for op in host_list %}
                                <option value="{{ op.id }}">{{ op.hostname }}</option>
                            {% endfor %}
                        </select>
                    <a id="ajax_submit_edit">确认编辑</a>    
                </form>
            </div>
    
    </body>
    
        <script src="static/js/jquery.min.js"></script>
        <script>
            $(function() {
                $('#add_host').click(function () {
                    $('.shade,.add-modal').removeClass('hide');
                });
                $('#cancel').click(function () {
                    $('.shade,.add-modal').addClass('hide');
                });
                
                $('#add_submit_ajax').click(function () {     #增加Application表操作的JS
                    $.ajax({
                        url: '/ajax_add_app',          #对应的url
                        //data: {'user': 123, 'host_list': [1,2,3,4]},  #使用传统方式传数据
                        data: $('#add_form').serialize(),        #使用简单的方式,直接使用<form>表单的ID然后serialize()直接自动形成键值方式提交
                        type: "POST",      #使用POST方式提交
                        dataType: 'JSON',    #使用JSON格式
                        traditional: true,    #开启列表接收,如‘host_List’: [1,2,3,4]这样后台就能拿到列表
                        success: function (obj) {
                           console.log(obj);    #前端调试台打印响应的数据
                        },
                        error: function () {  
    
                        }
                    })
                });
    
                $('.edit').click(function () {
                    $('.edit-modal,.shade').removeClass('hide');
    
                    hid_list = [];    #设置一个空列表
                    $(this).parent().prev().children().each(function () {  #信息表中找到主机关系对应的每一个对象标签做循环
                        var text = $(this).text();        #拿到appname
                        var hid = $(this).attr('hid');      #拿到主机ID
                        hid_list.push(hid);            #将主机ID放入空列表
                        console.log(hid,text);          
                    })
                    //console.log(hid_list)
                    $('#edit_form').find('select').val(hid_list);  #将主机列表放到多选框中得到默认选中的选项
    
    
                });
            })
        </script>
    </html>
    

      

  • 相关阅读:
    Use Module and Function instead of Class in Python
    以命令行方式使用Desktop版Ubuntu
    python中两种拷贝目录方法的比较
    查找重复文件并删除的工具
    Manage sshd Service on CentOS
    Java多线程间的数据共享
    并发 总结
    MapReduce 过程分析
    java能不能自己写一个类叫java.lang.System/String正确答案
    生产者消费者模式--阻塞队列--LOCK,Condition--线程池
  • 原文地址:https://www.cnblogs.com/kuku0223/p/7880601.html
Copyright © 2011-2022 走看看