• 巨蟒python全栈开发django7:多表增加和查询


    1.回顾内容&&补充

    补充1:

    补充2:

    这个选择的是第二个解释器.

    选择第一个的话,只是针对当前的项目,如果再开新项目的话,需要重新下载安装相关的包.

     

    点击保存,因为我们注释掉了,创建的语句,所以,我们没有添加数据成功,

     

    得到如上结果:

    <QueryDict: {'csrfmiddlewaretoken': ['qtSZFTXXdECQ6if9daiHeNoBIYXqIBCO9DlBZFHY2Es2ZkPWVOtQBazkA5g1BHNp'], '

    book_name': ['1'], 'book_price': ['100'], 'book_time': ['2019-03-21'], 'book_publish': ['py鱼出版社']}>

    我们可以想办法将上边的,打印出来的结果,转化成直接可以保存到数据库里边的信息,可以减少很多代码,因此,我们进行如下操作,先转化成字典,在把索引为0的元素去掉

    转化成字典的类型,下面我们添加数据

    如上图,添加成功

    成功将request.POST转化成字典类型的了

    运行程序:添加数据

    实际添加的结果:

    {'csrfmiddlewaretoken': 'Fza4TTOwBqqWgLeGFkC0UFqooYyyJoqWoJDGdFyxqqg89NOtnYN9h2B7g5R9CuBx', 'book_name': '1', 'book_price': '2', 'book_time': '2019-03-01', 'book_publish': '1312'}

    注意上边的结果,都是html中的input里边的name属性,我们需要对其进行修改

    已达到可以传递数据的目的(在这里我们把input里边的id和name,还有label里边的for属性,都修改成对应数据库字段的对应名字):

    修改之后,此时得到的结果:

    运行:

     此时结果,成功变成下边的刚才改的html文件

     

    我们通过变量先接收值,再经过删除第一个元素,索引为0的元素

    运行,添加书籍

    顺序为什么会有变化,因为我们进行了排序

     如果改成下边的这条语句

    运行,再看查询的结果,这时候刚才添加的结果,变成了最后一条

    注意,传递的参数,要和数据一一对应好.

    2.多对多表关系梳理和表创建

    下面处理多表之间的增删改查(图书管理系统之多表操作)

     

     多对多,产生第三张表

    新项目里边的models.py

    from django.db import models
    
    # Create your models here.
    class Author(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        author=models.OneToOneField(to='AuthorDetail',to_field='id')
    # 注意:to='AuthorDetail',可以写成to=AuthorDetail,但是必须将建立的类
    # AuthorDetail放在Author类上边,如果写成to='AuthorDetail'也就是映射的形式,
    # 就可以在上下都可以写了
    #思考客户表和学生表之间的关系
    class AuthorDetail(models.Model):
        id=models.AutoField(primary_key=True)
        address=models.CharField(max_length=32)
        tel=models.CharField(max_length=11)
    
    class Publish(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        addr=models.CharField(max_length=64)
    
    class Book(models.Model):
        id=models.AutoField(primary_key=True)
        title=models.CharField(max_length=32)
        publisher=models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
        #注意点一:1对多的关系要在多的表中建立"外键关系"
        #注意点二:这里的外键关系和1对1表的关系的区别是,1对1有unique的约束,这里没有unique的约束
        #注意点三:1对多关系中的1删除1条记录,多的这个也自然跟着删除1的对应记录
        #注意点四:1对多关系中的多删除1的对应的多条记录,才能手动再删除1的对应的记录
        authors=models.ManyToManyField(to='Author')
        #注意上边的这条语句中,数据库生成的表中并没有这条字段,
        #只是目前这个Book表里边,有这么一条属性,
        #这条语句的目的就是建立了第三张关系表,也就是下面的Book2Author表
        #将来查询的时候可以通过authors这条属性,查找到第三张表,
        # 但是数据库中的表没有这条字段,但是可以应用这条属性,进行表的寻找
    
    # class Book2Author(models.Model):
    #     id=models.AutoField(primary_key=True)
    #     book_id=models.ForeignKey(to='Book',to_field='id')
    #     author_id=models.ForeignKey(to='Author',to_field='id')
    #     #上边的两条字段相当一建立了两个1对多的关系
    """
    # 外键回顾mysql:
        create table Book(
        id int primary key auto_increment,
        author_id int,
        constraint xxx foreign key author_id references Author(id) on delete cascade 
        # 给外键起名字为xxx,t1表的author_id字段,指向Author(id)字段,级联删除
        );
    """

    配置settings里边的配置:

    mysql的引擎:

    #连接mysql的配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME':'orm1',     # 要连接的数据库,连接前需要创建好
            'USER':'root',    # 连接数据库的用户名
            'PASSWORD':'222',    # 连接数据库的密码
            'HOST':'127.0.0.1',       # 连接主机,默认本级
            'PORT':3306    #  端口 默认3306
        }
    }

    项目底下的__init__.py

    import pymysql
    pymysql.install_as_MySQLdb()
    # 意思就是用pymysql替换MySQLdb

    执行程序

    执行指令的快捷方式:

    执行命令:

     报了一个警告错误

    用Navicat进行了连接:

    点击两次确定,进入下列页面

     注意,这个库的名字要进行修改

    在Navicat里新建数据库orm2

    这时候,已经有orm2了

    删除上边的东西,重新连接一下

    执行,

     我们就可以看到五张表,如下图

    book表

    多对多的第三张表,注意写外键的时候,orm自动会在外键属性名的后边字段加上_id

    ORM如何删除数据库中刚才创建的那张表,将models的相关表的命令注释掉,然后重新运行刚才的两条命令,就可以成功删除了.

    如果手动,创建第三张表,orm的一些属性可能用不了,注意下有这个问题,碰到之后再说.

    3.多表连接正想反向查询语法(将创建的结果重新捋一下)

    如何向book表里边添加数据?

    思考如何给关系字段添加数据

    下面我们显示,在book表中插入数据的方式

     成功插入

    上边的插入方式写的是publisher,而不是publisher_id,注意这个细节

    所以上边的写法也是可以的

    运行,刷新,得到如下结果

    需要先在authordetail表中添加信息

     

     

    结果:

    结果如上所示

    运行:

    主要是,上边的代码没有注释,注释掉,之后得到的结果

    这样就插入到第三张表中了.

     

     

    得到结果

    重点:

     

    运行:

    这里显示没有问题

    看两个表

    看一下这个的结果:

    得到的结果如下所示:

     

    运行:

    __dict__将属性以字典的形式展现出来.

    4.关联表创建和查询数据的语法

     注意,对应关系字段加在哪个表里边,这张表朝外指向的就是正向,

    修改表关系的对应名字,

    执行命令

    yes

    author表里边成功改变

    运行:

     得到结果:武松

    通过ORM进行查询的,不是mysql的表来查的,通过对象关系进行查询的

    1对1关系,正向查询用字段,反向查询用表名

    结果:

     

    运行,得到结果:

    运行:

    这个意思就是找到了book表的控制器(也可以理解为接口)

    相当于是找到了(models.Book.objects)

    多对多正向查询:

    运行,得到结果:

    5.图书管理系统

     首先配置路径

    写函数

    创建页面:booklist.html

    目前我们引用网络的bootstrap样式,在bootstrap网上找到地址链接,引入下列地址:

    展示,通过div

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-Type" charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width" ,initial-scale="1">
        <!--上边这个表示手机版的调整尺寸-->
        <!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
    
    <div class="container"></div>
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <table class="table table-hover table-striped table-bordered">
                    <thead>
                    <tr>
                        <th>id</th>
                        <th>书名</th>
                        <th>出版社</th>
                        <th>作者</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one_book_obj in all_book_objs %}
                        <tr>
                            <td>{{ one_book_obj.id }}</td>
                            <td>{{ one_book_obj.title }}</td>
                            <td>{{ one_book_obj.publisher.name }}</td>
                            <td>{{ one_book_obj.authors.all.values.name }}</td>
                            {#  这个地方通过关联查找对应的作者关联找到所有书 ,模板渲染语言在这里不能加all(),只能写all#}
    {#                        将上边的语句,再写一遍for循环#}
    {#                        <td>#}
    {#                            {% for one_author_obj in one_book_obj.authors.all %}#}
    {##}
    {#                            {% endfor %}#}
    {#                        </td>#}
                        </tr>
                    {% endfor %}
                    </tbody>
                    {#for循环需要一行一行来#}
                </table>
            </div>
        </div>
    </body>
    </html>

    运行:得到结果:

    作者这里边没有信息,这样显然是不可以的.

    将html修改如下:

     这样就可以,拿到作者的对象

     

    如何只在中间加上逗号?

    需要用循环进行判断,只要不是最后一次,中间就有逗号,是最后一次就什么也不写

     

    这样我们就完成了在中间,加上逗号

     添加数据在表格中:(在book表中,因为多表关联,所以不可以删除数据,但是可以添加数据)

    保存一下,加上水浒传

    点击刷新,我们就可以拿到水浒传,

    添加数据的顺序:先添加作者的详细信息,尔康的详细信息

    再建立作者表的信息,尔康

    在这里book的id是4

     author的id是5

     

     

    这样,对应关系,就成功添加进去了

    只需要在前面加上一个序列号,就可以不按照顺序展示了,对html作出下列修改,就可以了

    运行,得到这样的结果:

    设置,向下居中

    运行,得到如下,成功往下移动,

    添加一个添加数据的按钮:

    首先是url:

    利用bootstrap的样式进行改写

    修改之后的样子:

    出版社这个位置要改成选择框,(因为选择框这个位置的publisher和其他有关联性)

    传参进行渲染add_book

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-Type" charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width" ,initial-scale="1">
        <!--上边这个表示手机版的调整尺寸-->
        <!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
        <title>Title</title>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
    
                <form class="form-horizontal">
                    <div class="form-group">
                        <label for="title" class="col-sm-2 control-label">书名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="title" placeholder="书名" name="title">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="publisher" class="col-sm-2 control-label">请选择出版社</label>
                        <div class="col-sm-10">
    {#                        <input type="password" class="form-control" id="inputPassword3" placeholder="Password">#}
                            {#一个放出版社,另一个放作者#}
                            <select name="publisher" id="publisher">
                                {% for one_pub in all_publisher  %}
                                {#每一个选项都是option#}
                                    <option value="{{ one_pub.id }}">{{ one_pub.name }}</option>
                                {% endfor %}
                            </select>
                        </div>
                    </div>
    
                <div class="form-group">
                        <label for="authors" class="col-sm-2 control-label">请选择作者</label>
                        <div class="col-sm-10">
    {#                        <input type="password" class="form-control" id="inputPassword3" placeholder="Password">#}
                            {#一个放出版社,另一个放作者#}
                            <select name="authors" id="authors">
                                {% for one_author in all_authors  %}
                                {#每一个选项都是option#}
                                    <option value="{{ one_author.id }}">{{ one_author.name }}</option>
                                {% endfor %}
                            </select>
                        </div>
                    </div>
    
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-default">提交</button>
                        </div>
                    </div>
                </form>
    
            </div>
        </div>
    </div>
    
    </body>
    </html>
    View Code

     注意要在booklist.html中添加按钮

     

    运行:

    点击,添加数据,得到下图:

    在select标签中,添加属性

     

    这时候,样式可以发生改变了,

    可以选择,多个作者,多个出版社的属性(点击,提交触发这个属性,)

     

    导入模块

    数据表的创建,起相同的名字的目的,就是为了操作起来,相对简单一些

    在表单中添加,中间件过滤

    问题是,现在少一个作者!!!!!????现在我们,在下面获取作者

     

    运行:

     

    提交数据

    服务端得到结果:

     

    选中之后,提交

    得到结果:

     创建的book表里边的authors属性

    此时Book表里边的字段:

    添加方式:

    测试经过删除之后的结果,对比上边的publisher&&publiser_id

    运行:提交数据

    得到的结果

    思考,如何对应起来?

    将html里边进行对应起来,也就是将下面,进行相关的修改,

    此时,我们再运行

    此时,就做好了对应关系,下面,我们开始运行,

    点击"添加数据"

    成功得到下边的结果:

    服务端的数据也,已经做好了对应

     总结:

    一对一:
    models.onetooneField(to=’表名’,to_field=’id’,)
    一对多
    在多的那个表里面写字段
    models.ForeignKey(to=’’)
     
    多对多:
    models.ManyToManyField(to=’表名’)
     
    增加:
     
        # pub_obj = models.Publish.objects.filter(id=1)[0]
        # 多对一插入数据方式1
        # models.Book.objects.create(
        #     title='jpm',
        #     publisher=pub_obj 
        #
        # )
        #多对一插入数据方式2
        # models.Book.objects.create(
        #     title='三国演义',
        #     publisher_id = 1
        #
        # )
     
        # 一对一插入数据方式
        # models.Author.objects.create(
        #     name='武松',
        #     age=18,
        #     author_id=1
        #
        # )
     
        # 多对多插入数据方式
        # 方式1
        # book_obj = models.Book.objects.get(id=2)
        #
        # lzs = models.Author.objects.get(id=1)
        # ws = models.Author.objects.get(id=2)
      # book_obj.authors.add(lzs ,ws )
     
     
    方式2
        # book_obj = models.Book.objects.get(id=2)
        # book_obj.authors.add(*[1,2])
        # book_obj.authors.add(1,2)
    View Code

    6.一定要及时回顾mysql数据库相关知识

  • 相关阅读:
    XML 浏览器支持
    浏览器中的XML
    C/C++中判断某一文件或目录是否存在
    C/C++程序员必须熟练应用的开源项目 -- 转
    VC 中窗口的销毁
    sql proc触发异常处理回滚
    为Array 添加indexOf
    Js的两种post方式
    sql 针对多个id或名称的分割和组合
    sql 查看语句的性能
  • 原文地址:https://www.cnblogs.com/studybrother/p/10452566.html
Copyright © 2020-2023  润新知