zoukankan      html  css  js  c++  java
  • Django 之 ORM

    Django ORM

    简介

    定义

    Django 框架自带的ORM 系统(python 还有其他ORM 模块如: SQLAlchemy

    特点

    1 配置简单 2 开发迅速 3 性能低于pysql

    ORM 定义

    对象关系映射(Object Relational Mapping,简称ORM)

    说明

    是将面向对象语言程序中的对象自动持久化到关系数据库中 (sql 语句转化 ODD(面向对象))

    转化中有性能损耗

    本质是一个中间件

     

    基本使用

    1 配置

    1 导包

    ------settings----
    # django 配置项

    # 数据库配置
    DATABASES = {
       'default': {
           'ENGINE': 'django.db.backends.mysql',
           'NAME': 'download',        #数据库名字
           'USER': 'root',          #账号

           'PASSWORD': 'mysql',    #密码
           'HOST': '127.0.0.1',     #IP
           'PORT': '3306',          #端口
           "OPTIONS": {"init_command": "SET default_storage_engine=INNODB;"}
      }
    }

    # 应用配置
    INSTALLED_APPS = [
       'django.contrib.admin',
       'django.contrib.auth',
       'django.contrib.contenttypes',
       'django.contrib.sessions',
       'django.contrib.messages',
       'django.contrib.staticfiles',
       'app01.apps.App01Config',]
    -----model.py----
    # 导入基类文件
    from django.db import models

    models.Model

    2 创建模型(类)
    # demo

    class VerifyCode(models.Model): # 创建模型类 对应数据库表
       # 定义类属性 对应表字段
       code = models.CharField("兑换码", max_length=50, help_text="兑换码")
       # 字段类型
       # CharField 对应char
       # DateTimeField 对应DateTime
       add_time = models.DateTimeField("添加时间", default=datetime.now, help_text="添加时间")
       is_true = models.BooleanField("是否使用", default=False, help_text="是否使用")

       class Meta:
       # Meta子类 可以定义一些有关数据库或者数据表的相关信息,这些相关信息我们称之为元数据
           verbose_name = "兑换码"
           verbose_name_plural = verbose_name

       def __str__(self):
           # "返回一个对象的描述信息
           return self.code

    3 迁移文件(关联数据库)
    命令
    python manage makemigrations
    python manage migrate
    # 已有数据库逆向成模型
    python manage.py inspectdb
    python manage.py inspectdb > app/models.py

     

     

    Django模型属性和MySQL数据库数据类型对应关系

    分类模型属性类型sql数据类型
    自增 AutoField int
    布尔 BooleanField tinyint
      NullBooleanField tinyint
    字符 CharField varchar
      EmailField varchar
      TextField longtext
    数字 IntegerField int
      DecimalField decimal
      FloatField double
    日期和时间 DateField date
      TimeField time
      DateTimeField datetime
    文件 FileField varchar
      ImageField varchar
    外键 ForeignKey alter table B add constraint A_B_Ids foreign key(Aid) references A(Ids)
      ManytoMany 建中间表再关联外键

     

     

    2 使用模型

    数据库操作(CURD)
    # 新增数据
    model_obj = VerifyCode()
    model_obj["code"] = "123"
    model_obj.save()
    # 查询操作
    model_obj1 = VerifyCode.objects.filter("code"="123")[0]
    # 更新操作
    model_obj1["code"] = "234"
    model_obj1.save()
    # 删除操作
    model_obj1.delete()

    # 还有其他方式这是用的比较多的

     

    使用技巧

    更多使用

    批量上传
    insert_list = []
    for i range(n):
       obj = OrderModel(a=1,b=2, ..)
       insert_list.append(obj)
    OrderModel.objects.bulk_create(insert_list)
    # bulk_create 有个小问题,当其中有一个数据错误的时候错误数据都会上传失败,优点是上传速度很快比正常快很多倍

     

    级联操作

    定义一张表上某字段的存在依赖于其他表或本表的字段

    强关联:(外键关联)

    定义: 在数据库层进行了强关联 数据有主从关系 ,修改主键从可能建受影响,且是自动发生的

    主键:不用操作

    从键:设置外键关联主键

     

    弱关联 :(逻辑关联)

    只在逻辑层进行数据关联,修改主键只能手动去改从建

     

    外键使用

    一,一对多使用(ForeignKey)

    # 案例 
    # 建立外键
    class User(models.Model):
    name = models.AutoField("id", help_text="id") # 一般默认会有这个可以不写
    name = models.CharField("名字", max_length=50, help_text="名字")

    class VerifyCode(models.Model):
     
       code = models.CharField("兑换码", max_length=50, help_text="兑换码")
       user=models.ForeignKey(User, to_field="id",related_name='SalesSite_Order', null=True, on_delete=models.CASCADE,help_text='用户')
    """
    on_delete设置
    CASCADE      删除级联,当父表的记录删除时,子表中与其相关联的记录也会删除
    PROTECT      子表记录所关联的父表记录被删除时,会报ProtectedError异常
    SET_NULL      子表记录所关联的父表记录被删除时,将子表记录中的关联字段设为NULL,注意:需要允许数据表的该字段为NULL。
    SET_DEFAULT      子表记录所关联的父表记录被删除时,将子表记录中的关联字段设为一个给定的默认值。
    DO_NOTHING      子表记录所关联的父表记录被删除时,什么也不做。
    """


    # 使用外键
    user_obj = User(name="reno")
    user_obj.save()
    code_obj = VerifyCode(code="123",user_obj)

    # 当删除主键时
    user_obj.delete()
    # 如果 on_delete=models.CASCADE 从键对应数据自动改变

    # 查询
    user_obj = code_obj.user # 得到主键对象
    code_query = user_obj.code_obj # 得到从键集合


    二,多对多使用(ManytoMany)

    多对多 情况会有不同,相当于两个键是互相依赖的没有主从概念,数据层的体现是会另外建一个中间表存储二者的关系,删除其中一方另一方没有影响,不过中间表对应部分删除,外键建在任意一边都可以

    # 案例
    # 建立外键
    class User(models.Model):
    name = models.AutoField("id", help_text="id") # 一般默认会有这个可以不写
    name = models.CharField("名字", max_length=50, help_text="名字")

    class VerifyCode(models.Model):
     
       code = models.CharField("兑换码", max_length=50, help_text="兑换码")
       user=models.ManyToMany(User, through="UserVerifyCode")  # through 建立中间表模型
       
    class UserVerifyCode(models.Model):
       user=models.ForeignKey(User,  on_delete=models.CASCADE)
       VerifyCode=models.ForeignKey(User,  on_delete=models.CASCADE)

    # 创建
    user_obj = User(name="reno")
    code_obj = VerifyCode(code="123")
    user_code_obj = UserVerifyCode(user_obj, code_obj)
    # 查
    code_query = user_obj.VerifyCode_set.all()
    user_query = code_obj.User.all()

     

  • 相关阅读:
    Java开发中的一些小技巧
    Java后端WebSocket的Tomcat实现
    Spring事务配置的五种方式 -- 越往后需要Spring版本越高
    Spring事务管理 -- 挺好
    java List 排序 Collections.sort() 对 List 排序
    java List 排序 Collections.sort()
    Java获得文件的创建时间(精确到秒)
    [JSP] c:forEach 输出序号 每行自动生成序号
    Unity3D研究院之在开始学习拓展编辑器
    同样的代码在java和c++中结果不同
  • 原文地址:https://www.cnblogs.com/renoyuan/p/12661042.html
Copyright © 2011-2022 走看看