zoukankan      html  css  js  c++  java
  • django操作数据库ORM

    
    

    django 通过外键操作ORM

    
    

    1.在模型层新建数据表


    class
    Country(models.Model): name = models.CharField(max_length=100) class Ctudent(models.Model): name = models.CharField(max_length=100) grade = models.PositiveIntegerField() country =models.ForeignKey(Country,on_delete=models.PROTECT)

    导入数据:

    from sales.models import *

    c1 = Country.objects.create(name='中国')
    c2 = Country.objects.create(name='美国')
    c3 = Country.objects.create(name='法国')
    Ctudent.objects.create(name='白月', grade=1, country=c1)
    Ctudent.objects.create(name='黑羽', grade=2, country=c1)
    Ctudent.objects.create(name='大罗', grade=1, country=c1)
    Ctudent.objects.create(name='真佛', grade=2, country=c1)
    Ctudent.objects.create(name='Mike', grade=1, country=c2)
    Ctudent.objects.create(name='Gus', grade=1, country=c2)
    Ctudent.objects.create(name='White', grade=2, country=c2)
    Ctudent.objects.create(name='White', grade=2, country=c2)
    Ctudent.objects.create(name='Napolen', grade=2, country=c3)

    查询出学生名字为白月的所属国家

    >>> s1 =Ctudent.objects.get(name='白月')
    >>> s1.country.name

    查询学生表里面一年级的学生

    >>> Ctudent.objects.filter(grade=1).values()

    查询出一年级的中国学生

    >>> Ctudent.objects.filter(grade=1,country__name="中国").values()

    指定字段显示查询一年级的中国学生

    >>> Ctudent.objects.filter(grade=1,country__name="中国").values("name",'country__name')
    <QuerySet [{'name': '白月', 'country__name': '中国'}, {'name': '大罗', 'country__name': '中国'}]>

    给字段取别名

    使用 annotate 方法

    >>> Ctudent.objects.annotate(countryname=F('country__name'),studentname=F('name')).filter(grade=1,countryname="中国").values("studentname",'countryname')
    <QuerySet [{'countryname': '中国', 'studentname': '白月'}, {'countryname': '中国', 'sname': '大罗'}]>

    反向访问:

    通过 表Model名转化为小写 ,后面加上一个 _set 来获取所有的反向外键关联对象

    >>> cn.ctudent_set.all()

    第二种实现反向访问的方法:

    在定义Model的时候,外键字段使用 related_name 参数,像这样

    class Country(models.Model):
        name = models.CharField(max_length=100)
    
    class Ctudent(models.Model):
        name = models.CharField(max_length=100)
        grade = models.PositiveIntegerField()
        country =models.ForeignKey(Country,on_delete=models.PROTECT
                                   ,related_name='ctudent')
    >>> cn = Country.objects.get(name='中国')
    >>> cn.ctudent.all()

    反向过滤:

    获得一年级学生的国家名

    >>> Country.objects.filter(ctudent__grade=1).values()

    去重

    使用 .distinct() 去重

    >>> Country.objects.filter(ctudent__grade=1).values().distinct()
    <QuerySet [{'id': 1, 'name': '中国'}, {'id': 2, 'name': '美国'}]>

    数据库事务:

    场景:例如我们需要在一次操作找那个添加订单的操作,但是添加订单需要一般需要有订单表和商品订单表,这样我们添加一张订单的时候就需要执行两次数据库的操作,假如第一涨表添加成功时,请求又来了,所以又要执行一次添加请求操作,这样会让第二张表的数据丢失。为此我们需要引入数据库事务来进行控制,当第一张表添加后又来一次新的请求。当订单添加不成功时,数据库会有回滚事务。

    django引入 with transaction.atomic() 来声明事务类型

    def addorder(request):
    
        info  = request.params['data']
    
        # 从请求消息中 获取要添加订单的信息
        # 并且插入到数据库中
    
        
        with transaction.atomic():
            new_order = Order.objects.create(name=info['name'] ,
                                             customer_id=info['customerid'])
    
            batch = [OrderMedicine(order_id=new_order.id,medicine_id=mid,amount=1)  
                        for mid in info['medicineids']]
            OrderMedicine.objects.bulk_create(batch)
    
    
        return JsonResponse({'ret': 0,'id':new_order.id})

    with transaction.atomic() 下面 缩进部分的代码,对数据库的操作,就都是在 一个事务 中进行了。

    如果其中有任何一步数据操作失败了, 前面的操作都会回滚。

    这就可以防止出现 前面的 Order表记录插入成功, 而后面的 订单药品 记录插入失败而导致的数据不一致现象。


    大家可以发现 插入 OrderMedicine 表中的数据 可能有很多条, 如果我们循环用 ```py OrderMedicine.objects.create(order_id=new_order.id,medicine_id=mid,amount=1) ``` 插入的话, 循环几次, 就会执行 几次SQL语句 插入的 数据库操作 这样性能不高。

    我们可以把多条数据的插入,放在一个SQL语句中完成, 这样会大大提高性能。

  • 相关阅读:
    linux安装navicat全程记录
    MySQL5.7.20报错Access denied for user 'root'@'localhost' (using password: NO)
    java中的异步处理和Feature接口(一)
    @Autowired注解与@Resource注解的区别与用法
    超详细MySQL安装及基本使用教程
    linux下mysql开启远程访问权限及防火墙开放3306端口
    mysql之my.cnf详解
    centos7 mysql 启动mysqld.service
    linux系统安装mysql数据库
    ExecutorService 的理解与使用
  • 原文地址:https://www.cnblogs.com/Neotester/p/12965407.html
Copyright © 2011-2022 走看看