精华内容
下载资源
问答
  • 主要介绍了Django中ORM找出内容不为空的数据实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  •  参数:CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. IntegerField  作用:用于保存一个整数. CommaSeparatedIntegerField  作用:用于存放逗号分隔的整数...
  • 主要给大家介绍了关于Django中ORM表的创建和增删改查等基本操作的方法,还给大家分享了django orm常用查询筛选的相关内容,分享出来供大家参考学习,需要的朋友们下面随着小编来一起学习学习吧。
  • 因此这里我们首先来介绍下外键在 Django 的使用。 类定义为 class ForeignKey(to,on_delete,**options) 。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,...
  • Django中ORM操作(增、删、改、查)

    千次阅读 2019-04-29 22:17:21
    当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段; 使用 MySQLdb 来连接数据库,并编写...类名 ------- 对应------数据库的表名 类属性 --------- 对应---------数...

    当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:

    1. 创建数据库,设计表结构和字段;
    2. 使用 MySQLdb 来连接数据库,并编写数据访问层代码;
    3. 业务逻辑层去调用数据访问层执行数据库操作。

    ORM的概念

    ORM:Object Relational Mapping(对象关系映射),是使用面向对象的思维来操作数据库。

    python中类名 --------------对应---------->数据库中的表名

    python类属性 -----------对应--------->数据库里的字段

    python类实例------------对应--------->数据库表里的一行数据
    orm
    orm
    obj.id obj.name.....类实例对象的属性。

    在django中,根据代码中的类自动生成数据库的表也叫–code first

    Django orm的优势:

    1. Django的orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句;

    2. 所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite…,如果数据库迁移,只需要更换Django的数据库引擎即可。

    常用字段

    • AutoField
      int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

    • IntegerField
      一个整数类型,范围在 -2147483648 to 2147483647。

    • CharField
      字符类型,必须提供max_length参数, max_length表示字符长度。

    • DateField
      日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

    • DateTimeField
      日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

    一、将用户保存到数据库(增)

    1. 创建模型类,生成对应的数据库表格
      models.py 文件:
    from django.db import models
    
    class Person(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32, null=False, unique=True)
        age = models.IntegerField()
        birthday = models.DateField()  # 日期, YYYY-MM-DD
    
        def __str__(self):
            msg = 'name:{}'.format(self.name)
            return msg
    
        class Meta():
            db_table = 'person'  # 修改数据库中表格的名称为 person
    
    1. 在命令行下执行
      (1)、同步数据库 : python manage.py makemigrations
      (2)、写入数据库: python manage.py migrate

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1. 将表单数据保存到数据库
      格式:类名.objects.create()
      类实例化:obj=models.类(属性=XX) obj.save()

    在这里插入图片描述
    页面显示 add_person.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加用户</title>
    </head>
    <body>
    <form action="/app01/add_person/" method="post">
        {% csrf_token %}
        <p>
            用户名: <input type="text" name="username">
        </p>
    
        <p>
            年龄: <input type="text" name="age">
        </p>
        <p>
            生日: <input type="text" name="bir">
        </p>
    
        <p>
            <input type="submit" value="添加">
        </p>
    </form>
    </body>
    </html>
    

    views.py 文件:

    def add_person(request):
        # 1.判断请求方式
        if request.method == 'POST':
            # 2. 获取表单提交过来的数据
            usrname = request.POST.get('username')
            age = request.POST.get('age')
            bir = request.POST.get('bir')
            # 3. 保存到数据库
            models.Person.objects.create(name=usrname, age=age, birthday=bir)
            # 重定向到所有用户页面
            return redirect('/app01/all_person/')
        return render(request, 'app01/add_person.html')
    

    二、显示用户列表

    语法: 类名.objects.all() 获取所有记录

    views.py 文件:

    def all_person(request):
        """展示所有的用户"""
        # 1.查询数据库中所有的记录
        person_lst = models.Person.objects.all()  # 获取所有对象
        # print(person_lst)
        # <QuerySet [<Person: Person object (3)>]> 是QuerySet类型的列表,当成list使用。
        # 2.展示到页面上
        return render(request, 'app01/all_person.html', {'person_lst': person_lst})
    

    all_person.html文件:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <a href="/app01/add_person/">添加用户</a>
    
    
    <table border="1">
        <tr>
            <td>序号</td>
            <td>id</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>生日</td>
            <td>操作</td>
        </tr>
        {% for person in person_lst %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ person.id }}</td>
                <td>{{ person.name }}</td>
                <td>{{ person.age }}</td>
                <td>{{ person.birthday|date:'Y-m-d' }}</td>
                <td>
                    <a href="/app01/edit_person/?id={{ person.id }}">修改</a>
                    <a href="/app01/delete_person/?id={{ person.id }}">删除</a>
                </td>
            </tr>
        {% endfor %}
    </table>
    
    </body>
    </html>
    

    在这里插入图片描述

    三、删除用户

    (1)语法:
    类名.objects.get(xxx).delete()
    类名.objects.filter(xxx).delete()

    views.py 文件:

    def delete_person(request):
        """根据id删除用户"""
        # 1.获取表单传递过来的id
        ids = request.GET.get('id')
        # print(id)
        # 2.删除数据库中对应的记录
        # person_obj = models.Person.objects.get(id=ids)  # 获取 person对象
        # print(person_obj) # Person object (3)
        # person_obj.delete()  # 删除数据库中的记录
        ret = models.Person.objects.filter(id=ids)  # filter() 根据条件进行过滤。
        ret.delete()
        print(ret)  # <QuerySet [<Person: Person object (3)>]>
    
        # 3.删除成功后,重定向到展示所有用户的界面
        return redirect('/app01/all_person/')
    

    模板已经在上面写出

    在这里插入图片描述

    四、修改用户

    **
    (1)语法:

    obj =类名.objects.get(‘xxx’) 
    obj.zz = xx
    obj.save()
    

    类名.objects.filter(‘xxx’).update(关键字(类中的属性)=值.....)

    def edit_person(request):
        """修改用户"""
        if request.method == 'POST':
            # 1.获取提交过来的数据
            usrname = request.POST.get('username')
            age = request.POST.get('age')
            bir = request.POST.get('bir')
            # 2.根据唯一标识去数据库中查询出对象
            # id = request.POST.get('id')
            # person_obj = models.Person.objects.get(id=id)
            # # 对象重新赋值
            # # 3.再将新的数据赋值给对象
            # person_obj.name = usrname
            # person_obj.age = age
            # person_obj.birthday = bir
            # person_obj.save()  # 将对象保存到数据库
            # 第二种方式保存修改数据:使用filter()  返回 QuerySet 集合,使用 update() 方法。
            id = request.POST.get('id')
            models.Person.objects.filter(id=id).update(name=usrname, age=age, birthday=bir)
    
            # 修改成功后重定向到所有用户页面
            return redirect('/app01/all_person/')
        else:
            """get 请求"""
        # 1.获取 表单提交过来的id
        id = request.GET.get('id')
        # 2. 根据id去数据库中查询记录
        person_obj = models.Person.objects.get(id=id)
        # 3. 显示到页面上
        return render(request, 'app01/edit_person.html', {'person_obj': person_obj})
    

    在这里插入图片描述

    edit_person.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>修改用户</title>
    </head>
    <body>
    <form action="/app01/edit_person/" method="post">
        <p>
            <input type="hidden" name="id" value="{{ person_obj.id }}">
        </p>
        {% csrf_token %}
        <p>
            用户名: <input type="text" name="username" value="{{ person_obj.name }}">
        </p>
    
        <p>
            年龄: <input type="text" name="age" value="{{ person_obj.age }}">
        </p>
        <p>
            生日: <input type="text" name="bir" value="{{ person_obj.birthday|date:'Y-m-d' }}">
        </p>
    
        <p>
            <input type="submit" value="保存">
        </p>
    </form>
    </body>
    </html>
    
    展开全文
  • Object Relational Mapping(ORM) ...简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序的对象自动持久化到关系数据库ORM在业务逻辑层和数据库层之间充当了桥梁的作用。 O...

    Object Relational Mapping(ORM)

    ORM介绍

    ORM概念

    对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

    简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

    ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

    ORM由来

    让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。

    几乎所有的软件开发过程中都会涉及到对象和关系数据库。在用户层面和业务逻辑层面,我们是面向对象的。当对象的信息发生变化的时候,我们就需要把对象的信息保存在关系数据库中。

    按照之前的方式来进行开发就会出现程序员会在自己的业务逻辑代码中夹杂很多SQL语句用来增加、读取、修改、删除相关数据,而这些代码通常都是重复的。

    ORM的优势

    ORM解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。 

    ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。

    让软件开发人员专注于业务逻辑的处理,提高了开发效率。

    ORM的劣势

    ORM的缺点是会在一定程度上牺牲程序的执行效率。

    ORM用多了SQL语句就不会写了,关系数据库相关技能退化...

    ORM总结

    ORM只是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。

    但我们不能指望某个工具能一劳永逸地解决所有问题,一些特殊问题还是需要特殊处理的。

    但是在整个软件开发过程中需要特殊处理的情况应该都是很少的,否则所谓的工具也就失去了它存在的意义。

    Django中的ORM

    Django项目使用MySQL数据库

    1. 在Django项目的settings.py文件中,配置数据库连接信息:

     

    2. 在Django项目的__init__.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库:

     

    Model

    在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表,

    基本情况:

    每个模型都是一个Python类,它是django.db.models.Model的子类。

    模型的每个属性都代表一个数据库字段。

    综上所述,Django为您提供了一个自动生成的数据库访问API,详询官方文档链接

     

    快速入门 

    下面这个例子定义了一个Person模型,包含first_name last_name

     

    first_name last_name是模型的字段。每个字段被指定为一个类属性,每个属性映射到一个数据库列。

    上面的Person模型将会像这样创建一个数据库表:

     

    一些说明:

    表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时。

    id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。

    本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句。

    Django支持MySQL5.5及更高版本。

    Django ORM 常用字段和参数

    常用字段

    AutoField

    int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

    IntegerField

    一个整数类型,范围在 -2147483648 to 2147483647。

    CharField

    字符类型,必须提供max_length参数, max_length表示字符长度。

    DateField

    日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。

    DateTimeField

    日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

    字段合集(争取记忆)

     

    自定义字段(了解为主)

     

    自定义char类型字段

     

    创建的表结构:

    附ORM字段与数据库实际字段的对应关系

     

    字段参数

    null

    用于表示某个字段可以为空。

    unique

    如果设置为unique=True 则该字段在此表中必须是唯一的 。

    db_index

    如果db_index=True 则代表着为此字段设置数据库索引。

    default

    为该字段设置默认值。

    时间字段独有

    DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。

    auto_now_add

    配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

    auto_now

    配置上auto_now=True,每次更新数据记录的时候会更新该字段。

     

    关系字段

    ForeignKey

    外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。

    ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。

    字段参数

    to

    设置要关联的表

    to_field

    设置要关联的表的字段

    related_name

    反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。

    例如:

    .

    当我们要查询某个班级关联的所有学生(反向查询)时,我们会这么写:

    models.Classes.objects.first().student_set.all()

    当我们在ForeignKey字段中添加了参数 related_name 后,

     

    当我们要查询某个班级关联的所有学生(反向查询)时,我们会这么写:

    models.Classes.objects.first().students.all()

    related_query_name

    反向查询操作时,使用的连接前缀,用于替换表名。

    on_delete

    当删除关联表中的数据时,当前表与其关联的行的行为。

    models.CASCADE

    删除关联数据,与之关联也删除

    models.DO_NOTHING

    删除关联数据,引发错误IntegrityError

    models.PROTECT

    删除关联数据,引发错误ProtectedError

    models.SET_NULL

    删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)

    models.SET_DEFAULT

    删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)

    models.SET

    删除关联数据,

    a. 与之关联的值设置为指定值,设置:models.SET(值)

    b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

     

    db_constraint

    是否在数据库中创建外键约束,默认为True。

    OneToOneField

    一对一字段。

    通常一对一字段用来扩展已有字段。

    示例

    一对一的关联关系多用在当一张表的不同字段查询频次差距过大的情况下,将本可以存储在一张表的字段拆开放置在两张表中,然后将两张表建立一对一的关联关系。

     

    字段参数

    to

    设置要关联的表。

    to_field

    设置要关联的字段。

    on_delete

    同ForeignKey字段。

    ManyToManyField

    用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系。

    字段参数

    to

    设置要关联的表

    related_name

    同ForeignKey字段。

    related_query_name

    同ForeignKey字段。

    symmetrical

    仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。

    举个例子:

     

    此时,person对象就没有person_set属性。

     

    此时,person对象现在就可以使用person_set属性进行反向查询。

    through

    在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。

    但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。

    through_fields

    设置关联的字段。

    db_table

    默认创建第三张表时,数据库中表的名称。

    多对多关联关系的三种方式 

    方式一:自行创建第三张表

     

    方式二:通过ManyToManyField自动创建第三张表

     

    方式三:设置ManyTomanyField并指定自行创建的第三张表

     

    注意:

    当我们需要在第三张关系表中存储额外的字段时,就要使用第三种方式。

    但是当我们使用第三种方式创建多对多关联关系时,就无法使用set、add、remove、clear方法来管理多对多的关系了,需要通过第三张表的model来管理多对多关系。

    元信息

    ORM对应的类里面包含另一个Meta类,而Meta类封装了一些数据库的信息。主要字段如下:

    db_table

    ORM在数据库中的表名默认是app_类名,可以通过db_table可以重写表名。

    index_together

    联合索引。

    unique_together

    联合唯一索引。

    ordering

    指定默认按什么字段排序。

    只有设置了该属性,我们查询到的结果才可以被reverse()。

    展开全文
  • djangoorm也是code first,所以学的时候,本质就分为两块: 根据类自动创建数据库表 根据类对数据库表的数据进行各种操作 手动创建mysql数据库,例如db_Django03 create database root ch
  • Django中ORM是啥?

    2019-04-25 20:38:34
    ORM中的“O”就是object,也就是我们说的对象;R指的是relations关系;M指的是mapping也就是映射。所以ORM是对象-关系-映射的简称。 ORM主要的作用是实现数据模型也数据库的解耦,即数据模型的设计不需要依赖特定的...

    ORM是啥是许多Django新手的苦恼。

    ORM中的“O”就是object,也就是我们说的对象;R指的是relations关系;M指的是mapping也就是映射。所以ORM是对象-关系-映射的简称。

    ORM主要的作用是实现数据模型也数据库的解耦,即数据模型的设计不需要依赖特定的数据库

    ORM有以下主要任务:

      1:根据对象的类型生成表的结构

      2:将对象,列表的操作,转化为sql语句

      3:将sql查询到的结果转化为对象,列表

    如下图所示:

     

    展开全文
  • Django中ORM所有基本操作

    千次阅读 2019-01-20 12:32:45
    limit,取第三条以后的数据,没有对应的SQL,类似的如:select * from User limit 3,10000000,从第3条开始取数据,取10000000条(10000000大于表数据条数) User.objects.all()[3:] offset,取出结果的第10-...

    model update常规用法
    假如我们的表结构是这样的

    class User(models.Model):
        username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
        is_active = models.BooleanField(default=False, verbose_name='激活状态')
    

    那么我们修改用户名和状态可以使用如下两种方法:

    方法一:

    User.objects.filter(id=1).update(username='nick',is_active=True)
    

    方法二:

    _t = User.objects.get(id=1)
    _t.username='nick'
    _t.is_active=True
    _t.save()
    

    方法一适合更新一批数据,类似于mysql语句update user set username=‘nick’ where id = 1

    方法二适合更新一条数据,也只能更新一条数据,当只有一条数据更新时推荐使用此方法,另外此方法还有一个好处,我们接着往下看

    具有auto_now属性字段的更新
    我们通常会给表添加三个默认字段

    自增ID,这个django已经默认加了,就像上边的建表语句,虽然只写了username和is_active两个字段,但表建好后也会有一个默认的自增id字段

    创建时间,用来标识这条记录的创建时间,具有auto_now_add属性,创建记录时会自动填充当前时间到此字段

    修改时间,用来标识这条记录最后一次的修改时间,具有auto_now属性,当记录发生变化时填充当前时间到此字段

    就像下边这样的表结构

    class User(models.Model):
        create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
        update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
        is_active = models.BooleanField(default=False, verbose_name='激活状态')
    

    当表有字段具有auto_now属性且你希望他能自动更新时,必须使用上边方法二的更新,不然auto_now字段不会更新,也就是:

    _t = User.objects.get(id=1)
    _t.username='nick'
    _t.is_active=True
    _t.save()
    

    json/dict类型数据更新字段
    目前主流的web开放方式都讲究前后端分离,分离之后前后端交互的数据格式大都用通用的json型,那么如何用最少的代码方便的更新json格式数据到数据库呢?同样可以使用如下两种方法:

    方法一:

    data = {'username':'nick','is_active':'0'}
    User.objects.filter(id=1).update(**data)
    

    同样这种方法不能自动更新具有auto_now属性字段的值

    通常我们再变量前加一个星号(*)表示这个变量是元组/列表,加两个星号表示这个参数是字典

    方法二:

    data = {'username':'nick','is_active':'0'}
    _t = User.objects.get(id=1)
    _t.__dict__.update(**data)
    _t.save()
    

    方法二和方法一同样无法自动更新auto_now字段的值

    注意这里使用到了一个dict方法

    方法三:

    _t = User.objects.get(id=1)
    _t.role=Role.objects.get(id=3)
    _t.save()
    

    ForeignKey字段更新
    假如我们的表中有Foreignkey外键时,该如何更新呢?

    class User(models.Model):
        create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
        update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
        is_active = models.BooleanField(default=False, verbose_name='激活状态')
        role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='角色')
    

    方法一:

    User.objects.filter(id=1).update(role=2)
    

    最简单的方法,直接让给role字段设置为一个id即可

    当然也可以用dict作为参数更新:

    User.objects.filter(id=1).update(**{'username':'nick','role':3})
    

    方法二:

    _role = Role.objects.get(id=2)
    User.objects.filter(id=1).update(role=_role)
    

    也可以赋值一个实例给role

    当然也可以用dict作为参数更新:

    _role = Role.objects.get(id=1)
    User.objects.filter(id=1).update(**{'username':'nick','role':_role})
    

    方法三:

    _t = User.objects.get(id=1)
    _t.role=Role.objects.get(id=3)
    _t.save()
    

    注意:这里的role必须赋值为一个对象,不能写id,不然会报错"User.role" must be a “Role” instance

    当使用dict作为参数更新时又有一点不同,如下代码:

    _t = User.objects.get(id=1)
    _t.__dict__.update(**{'username':'nick','role_id':2})
    _t.save()
    

    Foreignkey外键必须加上_id,例如:{‘role_id’:3}

    role_id后边必须跟一个id(int或str类型都可),不能跟role实例

    ManyToManyField字段更新
    假如我们的表中有ManyToManyField字段时更新又有什么影响呢?

    class User(models.Model):
        create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
        update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
        is_active = models.BooleanField(default=False, verbose_name='激活状态')
        role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='角色')
        groups = models.ManyToManyField(Group, null=True, verbose_name='组')
    

    m2m更新:m2m字段没有直接更新的方法,只能通过清空再添加的方法更新了

    _t = User.objects.get(id=1)
    _t.groups.clear()
    _t.groups.add(*[1,3,5])
    _t.save()
    

    add():m2m字段添加一个值,当有多个值的时候可用列表,参照上边例子

    _t.groups.add(2)
    
    _t.groups.add(Group.objects.get(id=2))
    

    remove():m2m字段移除一个值,,当有多个值的时候可用列表,参照上边例子

    _t.groups.remove(2)
    
    _t.groups.remove(Group.objects.get(id=2))
    

    clear():清空m2m字段的值

    Django model select的各种用法详解

    基本操作
    获取所有数据,对应SQL:select * from User

    User.objects.all()
    

    匹配,对应SQL:select * from User where name = ‘yky’

    User.objects.filter(name='yky')
    

    不匹配,对应SQL:select * from User where name != ‘yky’

    User.objects.exclude(name='yky')
    

    获取单条数据(有且仅有一条,id唯一),对应SQL:select * from User where id = 724

    User.objects.get(id=123)
    

    常用操作
    获取总数,对应SQL:select count(1) from User

    User.objects.count()
    

    获取总数,对应SQL:select count(1) from User where name = ‘运维咖啡吧’

    User.objects.filter(name='yky').count()
    

    大于,>,对应SQL:select * from User where id > 724

    User.objects.filter(id__gt=724)
    

    大于等于,>=,对应SQL:select * from User where id >= 724

    User.objects.filter(id__gte=724)
    

    小于,<,对应SQL:select * from User where id < 724

    User.objects.filter(id__lt=724)
    

    小于等于,<=,对应SQL:select * from User where id <= 724

    User.objects.filter(id__lte=724)
    

    同时大于和小于, 1 < id < 10,对应SQL:select * from User where id > 1 and id < 10

    User.objects.filter(id__gt=1, id__lt=10)
    

    包含,in,对应SQL:select * from User where id in (11,22,33)

    User.objects.filter(id__in=[11, 22, 33])
    

    不包含,not in,对应SQL:select * from User where id not in (11,22,33)

    User.objects.exclude(id__in=[11, 22, 33])
    

    为空:isnull=True,对应SQL:select * from User where pub_date is null

    User.objects.filter(pub_date__isnull=True)
    

    不为空:isnull=False,对应SQL:select * from User where pub_date is not null

    User.objects.filter(pub_date__isnull=True)
    

    匹配,like,大小写敏感,对应SQL:select * from User where name like ‘%sre%’,SQL中大小写不敏感

    User.objects.filter(name__contains="sre")
    

    匹配,like,大小写不敏感,对应SQL:select * from User where name like ‘%sre%’,SQL中大小写不敏感

    User.objects.filter(name__icontains="sre")
    

    不匹配,大小写敏感,对应SQL:select * from User where name not like ‘%sre%’,SQL中大小写不敏感

    User.objects.exclude(name__contains="sre")
    

    不匹配,大小写不敏感,对应SQL:select * from User where name not like ‘%sre%’,SQL中大小写不敏感

    User.objects.exclude(name__icontains="sre")
    

    范围,between and,对应SQL:select * from User where id between 3 and 8

    User.objects.filter(id__range=[3, 8])
    

    以什么开头,大小写敏感,对应SQL:select * from User where name like ‘sh%’,SQL中大小写不敏感

    User.objects.filter(name__startswith='sre')
    

    以什么开头,大小写不敏感,对应SQL:select * from User where name like ‘sh%’,SQL中大小写不敏感

    User.objects.filter(name__istartswith='sre')
    

    以什么结尾,大小写敏感,对应SQL:select * from User where name like ‘%sre’,SQL中大小写不敏感

    User.objects.filter(name__endswith='sre')
    

    以什么结尾,大小写不敏感,对应SQL:select * from User where name like ‘%sre’,SQL中大小写不敏感

    User.objects.filter(name__iendswith='sre')
    

    排序,order by,正序,对应SQL:select * from User where name = ‘yky’ order by id

    User.objects.filter(name='yky').order_by('id')
    

    多级排序,order by,先按name进行正序排列,如果name一致则再按照id倒叙排列

    User.objects.filter(name='yky').order_by('name','-id')
    

    排序,order by,倒序,对应SQL:select * from User where name = ‘yky’ order by id desc

    User.objects.filter(name='yky').order_by('-id')
    

    进阶操作
    limit,对应SQL:select * from User limit 3;

    User.objects.all()[:3]
    

    limit,取第三条以后的数据,没有对应的SQL,类似的如:select * from User limit 3,10000000,从第3条开始取数据,取10000000条(10000000大于表中数据条数)

    User.objects.all()[3:]
    

    offset,取出结果的第10-20条数据(不包含10,包含20),也没有对应SQL,参考上边的SQL写法

    User.objects.all()[10:20]
    

    分组,group by,对应SQL:select username,count(1) from User group by username;

    from django.db.models import Count
    User.objects.values_list('username').annotate(Count('id'))
    

    去重distinct,对应SQL:select distinct(username) from User

    User.objects.values('username').distinct().count()
    

    filter多列、查询多列,对应SQL:select username,fullname from accounts_user

    User.objects.values_list('username', 'fullname')
    

    filter单列、查询单列,正常values_list给出的结果是个列表,里边里边的每条数据对应一个元组,当只查询一列时,可以使用flat标签去掉元组,将每条数据的结果以字符串的形式存储在列表中,从而避免解析元组的麻烦

    User.objects.values_list('username', flat=True)
    

    int字段取最大值、最小值、综合、平均数

    from django.db.models import Sum,Count,Max,Min,Avg
    
    User.objects.aggregate(Count(‘id’))
    User.objects.aggregate(Sum(‘age’))
    

    时间字段

    匹配日期,date

    User.objects.filter(create_time__date=datetime.date(2018, 8, 1))
    User.objects.filter(create_time__date__gt=datetime.date(2018, 8, 2))
    

    匹配年,year

    User.objects.filter(create_time__year=2018)
    User.objects.filter(create_time__year__gte=2018)
    

    匹配月,month

    User.objects.filter(create_time__month__gt=7)
    User.objects.filter(create_time__month__gte=7)
    

    匹配日,day

    User.objects.filter(create_time__day=8)
    User.objects.filter(create_time__day__gte=8)
    

    匹配周,week_day

     User.objects.filter(create_time__week_day=2)
    User.objects.filter(create_time__week_day__gte=2)
    

    匹配时,hour

    User.objects.filter(create_time__hour=9)
    User.objects.filter(create_time__hour__gte=9)
    

    匹配分,minute

    User.objects.filter(create_time__minute=15)
    User.objects.filter(create_time__minute_gt=15)
    

    匹配秒,second

    User.objects.filter(create_time__second=15)
    User.objects.filter(create_time__second__gte=15)
    

    按天统计归档

    today = datetime.date.today()
    select = {'day': connection.ops.date_trunc_sql('day', 'create_time')}
    deploy_date_count = Task.objects.filter(
        create_time__range=(today - datetime.timedelta(days=7), today)
    ).extra(select=select).values('day').annotate(number=Count('id'))
    

    Q 的使用
    Q对象可以对关键字参数进行封装,从而更好的应用多个查询,可以组合&(and)、|(or)、~(not)操作符。

    例如下边的语句

    from django.db.models import Q
    
    User.objects.filter(
        Q(role__startswith='sre_'),
        Q(name='yky1') | Q(name='yky2')
    )
    

    转换成SQL语句如下:

    select * from User where role like 'sre_%' and (name='yky1' or name='yky2')
    

    通常更多的时候我们用Q来做搜索逻辑,比如前台搜索框输入一个字符,后台去数据库中检索标题或内容中是否包含

    _s = request.GET.get('search')
    
    _t = Blog.objects.all()
    if _s:
        _t = _t.filter(
            Q(title__icontains=_s) |
            Q(content__icontains=_s)
        )
    
    return _t
    

    外键:ForeignKey
    表结构:

    class Role(models.Model):
        name = models.CharField(max_length=16, unique=True)
    
    
    class User(models.Model):
        username = models.EmailField(max_length=255, unique=True)
        role = models.ForeignKey(Role, on_delete=models.CASCADE)
    

    正向查询:

    查询用户的角色名

    _t = User.objects.get(username='运维咖啡吧')
    _t.role.name
    

    反向查询:

    查询角色下包含的所有用户

    _t = Role.objects.get(name='Role03')
    _t.user_set.all()
    

    另一种反向查询的方法:

    _t = Role.objects.get(name='Role03')
    

    这种方法比上一种_set的方法查询速度要快

    User.objects.filter(role=_t)
    

    第三种反向查询的方法:

    如果外键字段有related_name属性,例如models如下:

    class User(models.Model):
        username = models.EmailField(max_length=255, unique=True)
        role = models.ForeignKey(Role, on_delete=models.CASCADE,related_name='roleUsers')
    

    那么可以直接用related_name属性取到某角色的所有用户

    _t = Role.objects.get(name = 'Role03')
    _t.roleUsers.all()
    M2M:ManyToManyField
    

    表结构:

    class Group(models.Model):
        name = models.CharField(max_length=16, unique=True)
    
    class User(models.Model):
        username = models.CharField(max_length=255, unique=True)
        groups = models.ManyToManyField(Group, related_name='groupUsers')
    

    正向查询:

    查询用户隶属组

    _t = User.objects.get(username = '运维咖啡吧')
    _t.groups.all()
    

    反向查询:

    查询组包含用户

    _t = Group.objects.get(name = 'groupC')
    _t.user_set.all()
    

    同样M2M字段如果有related_name属性,那么可以直接用下边的方式反查

        _t = Group.objects.get(name = 'groupC')
        _t.groupUsers.all()
        get_object_or_404
    

    正常如果我们要去数据库里搜索某一条数据时,通常使用下边的方法:

    _t = User.objects.get(id=734)
    

    但当id=724的数据不存在时,程序将会抛出一个错误

    abcer.models.DoesNotExist: User matching query does not exist.
    为了程序兼容和异常判断,我们可以使用下边两种方式:

    方式一:get改为filter

    _t = User.objects.filter(id=724)
    取出_t之后再去判断_t是否存在
    方式二:使用get_object_or_404

    from django.shortcuts import get_object_or_404
    
    _t = get_object_or_404(User, id=724)
    

    get_object_or_404方法,它会先调用django的get方法,如果查询的对象不存在的话,则抛出一个Http404的异常
    实现方法类似于下边这样:

    from django.http import Http404
    
    try:
        _t = User.objects.get(id=724)
    except User.DoesNotExist:
        raise Http404
    get_or_create
    

    顾名思义,查找一个对象如果不存在则创建,如下:

    object, created = User.objects.get_or_create(username='yky1')
    

    返回一个由object和created组成的元组,其中object就是一个查询到的或者是被创建的对象,created是一个表示是否创建了新对象的布尔值

    实现方式类似于下边这样:

    try:
        object = User.objects.get(username='yky1')
    
        created = False
    exception User.DoesNoExist:
        object = User(username='yky1')
        object.save()
    
        created = True
    
    returen object, created
    

    执行原生SQL
    Django中能用ORM的就用它ORM吧,不建议执行原生SQL,可能会有一些安全问题,如果实在是SQL太复杂ORM实现不了,那就看看下边执行原生SQL的方法,跟直接使用pymysql基本一致了

    from django.db import connection
    
    with connection.cursor() as cursor:
        cursor.execute('select * from accounts_User')
        row = cursor.fetchall()
    
    return row
    

    注意这里表名字要用app名+下划线+model名的方式

    展开全文
  • django中ORM的事务操作

    2018-05-30 11:29:00
    djangoORM中,有两种使用事务的方式(注意,mysql需要是innodb引擎) 装饰器 from django.db import transaction @transaction.atomic def viewfunc(request): # 下面的代码在一个事务中执行,一但出现异常,整个...
  • django中orm反向查询 _set

    千次阅读 2019-04-04 21:07:30
    # 循环这个出版社对象列表,在书籍表匹配每一个出版社对象,匹配到就返回书籍对象列表,没有就是空的对象列表,该书籍对象,有具体的出版社对象 books_obj_list = [] for publishers_obj in publisher_obj_list: ...
  • 通过在Django中创建表来进一步解释(这里用到的数据库是MySQL) 因为我们用到的是MySQL所以必须连接的是MySQL的数据库进行同步,在项目的__init__py文件设置Django连接数据库 import pymysql pymysq...
  • 先定义两个模型,一个是A,一个是B,是一对多的类型。 class A(models.Model): name= models.CharField('名称', max_length=32) class B(models.Model): a= models.ForeignKey(A, verbose_name='A\u7c7b',related...
  • Django中ORM聚合查询aggregate和分组查询annotate 聚合查询-aggregate 聚合查询是使用aggregate()过滤器调用聚合函数. 聚合函数从django.db.models引入 聚合函数包括: Avg 平均,Count 数量,Max 最大,Min 最小,...
  • 有时候在测试django中一些模块时,不想重新跑一整个django项目,只想跑单个文件,正好写在if __name__ == ‘__main__’: 这样也不会打扰到正常的代码逻辑 方法 正常方法 大家都知道的方法就是’python manage.py ...
  • Django中ORM的锁和事务

    千次阅读 2019-05-30 19:47:28
    Django中ORM的锁和事务一、锁1.行级锁2.表锁二、事务1.全局开启2.局部使用事务 一、锁 1.行级锁 select_for_update(nowait=False, skip_locked=False) #注意必须用在事务里面,至于如何开启事务,我们看下面的事务...
  • Django中ORM找出内容不为空的数据

    千次阅读 2019-05-27 23:06:05
    django操作数据库的时候如何找出内容不为空的数据呢? from django.db.models import Q class Index(VIew): def get(self, request): userObj = models.Asset.objects.filter(~Q(asset_id = '') return ...
  • 我就废话不多说了,大家还是直接看代码吧~ result= Booking.objects.filter() #方法一 .exists() if result.exists(): print "QuerySet has Data" else: print "QuerySet is empty" #方法二 .count()==0 ...
  • 单独提取DjangoORM

    2017-04-11 18:19:58
    自制单独提取的DjangoORM,可以使用manage.py inspectdb 从数据库直接生成model,简单方便,稍微简单的配置数据库信息就可以让一些小的APP直接使用djangoORM。单独提取的文件总大小为8KB。操作方法与在Django内使用...
  • django中ORM的各个方法及返回类型

    千次阅读 2019-09-03 20:38:50
    28.列举Django ORM中的方法(QuerySet对象的方法) 1.返回QuerySet对象的方法: all() filter() exclude() order_by() reverse() distinct() select_related() prefetch_related() only() de...
  • Django中ORM之或语句查询

    千次阅读 2019-05-28 15:33:48
    比如数据库表有显示器1和显示器2,那么如何在django中模糊查询出显示器1和显示器2呢 首先导入模块 from django.db.models import Q class GetDisplay(View): class GetDisplay(View): def post(self, request)...
  • 记录一下 GoodsSPU.objects.values("spu_code").... 我们应该跟上django 的order_by(), 进行相关的排序,最后得到的数据就是我们去重后的结果了. GoodsSPU.objects.values("spu_code").distinct().order_by('spu_code')
  • Django中ORM的查询

    2021-03-12 15:13:55
    Django中ORM的查询 Django内置的ORM查询,以字段名__查询方式来进行查询,下方是实例代码 def query_orm(request): # __exact精确查找,name是字段名,下面的写法就是name这个字段精确查找为西游记的数据 book = Book....
  • ORM对应关系 类 —&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 数据表 对象 —&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,338
精华内容 11,735
关键字:

django中orm