zoukankan      html  css  js  c++  java
  • Django【第5篇】:Django之ORM数据库操作

    django之ORM数据库操作

    一、ORM介绍

    映射关系:

      表名 --------------------》类名

      字段--------------------》属性

      表记录-----------------》类实例化对象

    ORM的两大功能:

      操作表:

        - 创建表

        - 修改表

        - 删除表

      操作数据行:

        - 增删改查

    ORM利用pymysql第三方工具链接数据库

    Django没办法帮我们创建数据库,只能我们创建完之后告诉它,让django去链接

    二、创建表之前的准备工作

    一、自己创建数据库

    二、在settings里面配置mysql数据库链接

      sqlite3------改为mysql

    复制代码
    # 修改django默认的数据库的sqlite3为mysql
    DATABASES = {
        'default': {
                'ENGINE': 'django.db.backends.mysql', #通过这个去链接mysql
                'NAME': 'djangotsgl',
                'USER':'root',
                'PASSWORD':'123456',
                'HOST':'localhost',
                'PORT':'3306',
            }
        }            
    复制代码

      这样写上以后django会默认的就去链接数据库,这时你会看到报错了,那么解决的办法就是下面的这样

    三、app01中的--init--文件

    import pymysql
    pymysql.install_as_MySQLdb()

    四、创建数据库表

    models.py

    复制代码
    class Book(models.Model):  #必须要继承的
        nid = models.AutoField(primary_key=True)  #自增id(可以不写,默认会有自增id)
        title = models.CharField(max_length=32)
        publishDdata = models.DateField()  #出版日期
        author = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5,decimal_places=2)  #一共5位,保留两位小数
        
    复制代码

     执行命令创建:(需要记住的!!!) 

    python3 manage.py makemigrations   创建脚本
    python3 manage.py migrate   迁移

    具体例子实现

    model.py

    urls.py

    views.py

    template /index.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width">
     7     <title>Title</title>
     8     <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
     9     <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    10     <style>
    11         table{
    12             margin-top: 50px;
    13         }
    14     </style>
    15 </head>
    16 <body>
    17 <div class="containers">
    18     <div class="row">
    19         <div class="col-md-9 col-md-offset-2">
    20             <table class="table table-hover">
    21                 <thead>
    22                     <tr>
    23                         <th>编号</th>
    24                         <th>书名</th>
    25                         <th>出版日期</th>
    26                         <th>作者</th>
    27                         <th>价钱</th>
    28                         <th>操作</th>
    29                     </tr>
    30                 </thead>
    31                 <tbody>
    32                 {% for book in book_list %}
    33                     <tr>
    34                             <td>{{ book.nid }}</td>
    35                             <td>{{ book.title }}</td>
    36                             <td>{{ book.publishDdata|date:'Y-m-d' }}</td>
    37                             <td>{{ book.author }}</td>
    38                             <td>{{ book.price }}</td>
    39                             <td>
    40                                 <a href="/del/{{ book.nid }}"><button class="btn btn-danger">删除</button></a>
    41                                 <a href="/edit/{{ book.nid }}"><button class="btn btn-success">编辑</button></a>
    42                                 <a href="/add/"><button class="btn btn-primary">添加</button></a>
    43                             </td>
    44                     </tr>
    45                 {% endfor %}
    46                 </tbody>
    47             </table>
    48         </div>
    49     </div>
    50 </div>
    51 </body>
    52 </html>
    图片内容具体

     五、查看数据库的sql语句(加在settings.py)

    复制代码
    查看数据库执行代码
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    复制代码

    一、多对多的正反向查询

    复制代码
    class Class(models.Model):
        name = models.CharField(max_length=32,verbose_name="班级名")
        course = models.CharField(verbose_name="课程",max_length=32)
        def __str__(self):
            return self.name
    
    class Teacher(models.Model):
        name = models.CharField(max_length=23,verbose_name="姓名")
        classes = models.ManyToManyField(verbose_name="所属班级",to="Class")
        def __str__(self):
            return self.name
    复制代码

    题目1:查找娜娜老师所带的班级

    复制代码
            # 方式一:基于对象的查找
            obj = models.Teacher.objects.filter(name="娜娜").first()
            print(obj.classes.all())
            print("娜娜老师带的班级",obj.classes.values("name"))
            # 方式二:基于双下划线的查找
            obj_cls = models.Teacher.objects.filter(name="娜娜").values("classes__name")
            print("娜娜老师带的班级",obj_cls)
    复制代码

    注意:要说明的是多对多的查询用.all,,查单个的时候用.values或者values_list,不要用obj.classes.name,,这样查到的会是None,反向查询也是如此。我就是犯了这样的错,引以为戒。。

    总结:不管是一对多,还是多对多,要是查询多得一方就得用all()

    运行结果截图:

    表结构:

    复制代码
    from django.db import models
    
    # Create your models here.
    # 一个学生有一个班级,一个班级可以有好多学生,所以是
    # 一对多的关系,关联字段放在多的一方
    class Student(models.Model):
        name = models.CharField(max_length=32,verbose_name="姓名")
        age = models.IntegerField(verbose_name="年龄")
        classes = models.ForeignKey(to="Class",verbose_name="所属班级")
        def __str__(self):
            return self.name
    
    class Class(models.Model):
        name = models.CharField(max_length=32,verbose_name="班级名")
        course = models.CharField(verbose_name="课程",max_length=32)
        def __str__(self):
            return self.name
    
    class Teacher(models.Model):
        name = models.CharField(max_length=23,verbose_name="姓名")
        classes = models.ManyToManyField(verbose_name="所属班级",to="Class")
        def __str__(self):
            return self.name
    复制代码

    2、查询海燕在那个班级

      # 方式一:
        print("多多所在的班级",models.Student.objects.filter(name="多多").values("classes__name"))
        # 方式二:
        obj_cls = models.Student.objects.filter(name="多多").first()
        print("多多所在的班级",obj_cls.classes.name)

    3、查询多多所在班的老师的姓名

      print("多多所在班的老师的姓名",models.Student.objects.filter(name="多多").values("classes__teacher__name"))

    4、查询软件测试151班的所有学生的姓名

     print("软件测试151班的所有学生的姓名",models.Class.objects.filter(name="软件测试151").values("student__name"))
     obj = models.Class.objects.filter(name="软件测试151").first()
     # print("软件测试151班的所有学生的姓名",obj.student_set.name)  #这样打印的结果是None
     print("软件测试151班的所有学生的姓名",obj.student_set.all().values("name"))

    二、需要掌握的一个很重要的知识点

    1、form表单中要用submit,如果用button切记要加上type,不然button默认的type是submit,会有影响

      <button class="login" type="button">注册</button>

    复制代码
    <button type="button" onclick="doValidation();">提交</button>
    <input type="button" onclick="doValidation();" value="提交"/>
    上面两种写法是对的,功能一样。
    
    <button onclick="doValidation();">提交</button>
    如果写成这种,默认为submit,本来doValidation方法里有提交功能了,
    再加上按钮也是提交功能,会提交两次。所以使用按钮时最好指定type类型。
    复制代码
  • 相关阅读:
    redux核心知识
    react性能优化要点
    react-router4的使用备注
    selenium启动Chrome配置参数问题
    Navicat15最新版本破解和破解报错总结
    Silence主题美化-部署
    vscode打开文件,中文显示乱码(已解决)
    Windows下Charles从下载安装到证书设置和浏览器抓包
    python下的selenium和chrome driver的安装
    Python 直接赋值、浅拷贝和深度拷贝解析
  • 原文地址:https://www.cnblogs.com/mqhpy/p/11204008.html
Copyright © 2011-2022 走看看