[实验] Django 实现数据原子性

注意:

本实验是接着 《Django 自定义逻辑添加(通过自定义 save 对象实现)(一次性完成多对多表数据的插入)》而继续的

正文:

将 mysite/user/models.py 中的以下内容:

class Clazz(models.Model):
    cname = models.CharField(max_length=30)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    score = models.PositiveBigIntegerField()
    cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)

    def __str__(self):
        return u'Student:%s,%s'%(self.sname,self.score)

    def  save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        try:
            self.cls = Clazz.objects.get(cname=self.cls.cname)
        except Clazz.DoesNotExist:
            self.cls = Clazz.objects.create(cname=self.cls.cname)

        #Insertion of student table
        models.Model.save(self, force_insert=False, force_update=False,using=None, update_fields=None)

修改为:

class Clazz(models.Model):
    cname = models.CharField(max_length=30)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    score = models.PositiveBigIntegerField()
    cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)

    def __str__(self):
        return u'Student:%s,%s'%(self.sname,self.score)

    from django.db.transaction import atomic
    @atomic
    def  save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        try:
            self.cls = Clazz.objects.get(cname=self.cls.cname)
        except Clazz.DoesNotExist:
            self.cls = Clazz.objects.create(cname=self.cls.cname)

        #Insertion of student table
        models.Model.save(self, force_insert=False, force_update=False,using=None, update_fields=None)

[实验] Django 数据修改

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤目录:

步骤一:进入相应的 Django 环境

步骤二:导入数据修改 F 模块

步骤三:设置一个显示上一句 SQL 语句的函数

步骤四:进行数据修改
4.1 单独修改某一条数据
4.1.1 单独修改某一条数据
4.1.2 显示单独修改某一条数据 SQL 语句
4.2 批量修改数据
4.2.1 批量修改数据
4.2.2 显示批量修改数据的 SQL 语句

补充:get 无法对获得的结果进行操作

具体的操作步骤:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:导入数据修改 F 模块

>>> from django.db.models import Q,F

(补充:这里同时也倒入了 Q 模块,后面的实验会用到 Q 模块)

步骤三:设置一个显示上一句 SQL 语句的函数

>>> def showsql():
...     from django.db import connection
...     print(connection.queries[-1]['sql'])
... 

步骤四:进行数据修改
4.1 单独修改某一条数据
4.1.1 单独修改某一条数据

>>> Student.objects.filter(id=3).update(score=F('score')+5)
1


补充:
1) 这里以给 id 等于 3 的数据的 score 值添加 5 为例
2) 这里共修改了 1 条数据

4.1.2 显示单独修改某一条数据 SQL 语句

>>> showsql()
UPDATE `user_student` SET `score` = (`user_student`.`score` + 5) WHERE `user_student`.`id` = 3

(补充:这里以给 id 等于 3 的数据的 score 值添加 5 为例)

4.2 批量修改数据
4.2.1 批量修改数据

>>> Student.objects.filter(Q(id__gt=3)).update(score=F('score')+5)
3


补充:
1) 这里以给 id 大于 3 的数据的 score 值添加 5 为例
2) 这里共修改了 3 条数据

4.2.2 显示批量修改数据的 SQL 语句

>>> showsql()
UPDATE `user_student` SET `score` = (`user_student`.`score` + 5) WHERE `user_student`.`id` > 3

(补充:这里以给 id 大于 3 的数据的 score 值添加 5 为例)

补充:get 无法对获得的结果进行操作

>>> Student.objects.get(id=3).update(score=33)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'update'


补充:
1) 前面 filter 返回结果是 QuerySet,所以可以被 update 操作
2) 现在 get 的返回结果是一个对象,所以不能被 update 操作

[实验] Django 逻辑条件数据查询

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤目录:

步骤一:进入相应的 Django 环境

步骤二:导入逻辑条件查询 Q 模块

步骤三:设置一个显示上一句 SQL 语句的函数

步骤四:进行逻辑条件查询
4.1 Django 进行与查询
4.1.1 通过 Q 查询进行与查询
4.1.1.1 通过 Q 查询进行与查询
4.1.1.2 显示通过 Q 查询进行与查询的 SQL 语句
4.1.2 通过 filter 进行与查询
4.1.2.1 通过 filter 进行与查询
4.1.2.2 显示通过 filter 进行与查询的 SQL 语句
4.2 Django 进行或查询
4.2.1 通过 Q 查询进行或查询
4.2.2 显示通过 Q 查询进行或查询的 SQL 语句
4.3 Django 进行非查询
4.3.1 通过 Q 查询进行非查询
4.3.2 显示通过 Q 查询进行非查询的 SQL 语句
4.4 Django 进行与非组合查询
4.4.1 通过 Q 查询进行与非组合查询
4.4.2 显示通过 Q 查询进行与非组合查询的 SQL 语句

具体的操作步骤:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:导入逻辑条件查询 Q 模块

>>> from django.db.models import Q

步骤三:设置一个显示上一句 SQL 语句的函数

>>> def showsql():
...     from django.db import connection
...     print(connection.queries[-1]['sql'])
... 

步骤四:进行逻辑条件查询
4.1 Django 进行与查询
4.1.1 通过 Q 查询进行与查询
4.1.1.1 通过 Q 查询进行与查询

>>> Student.objects.filter(Q(sname='lisi')&Q(score=80))
<QuerySet [<Student: Student:lisi,80>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例
2) 这里共查询到了 1 条数据

4.1.1.2 显示通过 Q 查询进行与查询的 SQL 语句

>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`sname` = 'lisi' AND `user_student`.`score` = 80) LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例)

4.1.2 通过 filter 进行与查询
4.1.2.1 通过 filter 进行与查询

>>> Student.objects.filter(sname='lisi',score=80)
<QuerySet [<Student: Student:lisi,80>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例
2) 这里共查询到了 1 条数据

4.1.2.2 显示通过 filter 进行与查询的 SQL 语句

>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`score` = 80 AND `user_student`.`sname` = 'lisi') LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例)

4.2 Django 进行或查询
4.2.1 通过 Q 查询进行或查询

>>> Student.objects.filter(Q(sname='zhangsan')|Q(score=90))
<QuerySet [<Student: Student:zhangsan,60>, <Student: Student:wangwu,90>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件或 score=90 条件的数据为例
2) 这里共查询到了 1 条数据

4.2.2 显示通过 Q 查询进行或查询的 SQL 语句

>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`sname` = 'zhangsan' OR `user_student`.`score` = 90) LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件或 score=90 条件的数据为例)

4.3 Django 进行非查询
4.3.1 通过 Q 查询进行非查询

>>> Student.objects.filter(~Q(sname='zhangsan'))
<QuerySet [<Student: Student:lisi,80>, <Student: Student:wangwu,90>, <Student: Student:zhaoliu,70>, <Student: Student:xueer,70>, <Student: Student:huangyi,70>]>


补充:
1) 这里以查询 sname=’zhangsan’ 条件不成立的数据为例
2) 这里共查询到了 5 条数据

4.3.2 显示通过 Q 查询进行非查询的 SQL 语句

>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE NOT (`user_student`.`sname` = 'zhangsan') LIMIT 21

(补充:这里以查询 sname=’zhangsan’ 条件不成立的数据为例)

4.4 Django 进行与非组合查询
4.4.1 通过 Q 查询进行与非组合查询

>>> Student.objects.filter(~Q(sname='zhangsan',score=90))
<QuerySet [<Student: Student:zhangsan,60>, <Student: Student:lisi,80>, <Student: Student:wangwu,90>, <Student: Student:zhaoliu,70>, <Student: Student:xueer,70>, <Student: Student:huangyi,70>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件不成立的数据为例
2) 这里共查询到了 1 条数据

4.4.2 显示通过 Q 查询进行与非组合查询的 SQL 语句

>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE NOT (`user_student`.`score` = 90 AND `user_student`.`sname` = 'zhangsan') LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件不成立的数据为例)

[实验] Django 自定义一个数据查询函数

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:自定义一个查询对象

>>> def test(sql):
...     from django.db import connection
...     with connection.cursor() as c:
...         c.execute(sql)
...         for info in c.fetchall():
...             print(info)
...

(补充:这里以自定义名为 test 的自定义查询对象为例)

步骤三:使用自定义查询对象查询数据

>>> test('select * from user_clazz')
(1, 'Class1')
(2, 'Class2')


补充:这里以
1) 使用 test 对象
2) 执行 select * from user_clazz SQL 语句
3) 查询结果是 1 Class1,2 Class2 两条数据
为例

[实验] Django 通过 SQL 语句进行数据查询

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤目录:

步骤一:进入相应的 Django 环境

步骤二:Django SQL 语句完全查询

步骤三:Django SQL 语句部分查询
3.1 导入 Django SQL 语句部分查询的模块
3.2 Django SQL 语句部分查询(含主键查询)
3.2.1 创建游标(含主键查询)
3.2.2 查询数据并导入游标(含主键查询)
3.2.3 将游标里的数据导入到变量里(含主键查询)
3.2.4 将游标里的数据以对象的形式显示出来(含主键查询)
3.2.5 将游标里的数据以列表的形式显示出来(含主键查询)
3.2.6 关闭游标(含主键查询)
3.3 Django SQL 语句部分查询(不包含主键)
3.3.1 创建游标(不包含主键)
3.3.2 查询数据并导入游标(不包含主键)
3.3.3 将游标里的数据导入到变量里(不包含主键)
3.3.4 将游标里的数据以对象的形式显示出来(不包含主键)
3.2.5 将游标里的数据以列表的形式显示出来(不包含主键)
3.2.5 关闭游标(不包含主键)
3.3 Django SQL 语句部分查询(只查询一条数据)
3.3.1 创建游标(只查询一条数据)
3.3.2 查询数据并导入游标(只查询一条数据)
3.3.4 将游标里的数据以对象的形式显示出来(只查询一条数据)
3.2.5 关闭游标(只查询一条数据)

具体的操作步骤:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:Django SQL 语句完全查询

>>> user = Student.objects.raw('select * from user_student')
>>> for s in user:
...     print(s)
... 
Student:zhangsan,60
Student:lisi,80
Student:wangwu,90
Student:zhaoliu,70
Student:xueer,70
Student:huangyi,70

(补充:这里以查看 user_student 表中的所有数据为例)

步骤三:Django SQL 语句部分查询
3.1 导入 Django SQL 语句部分查询的模块

>>> from django.db import connection

3.2 Django SQL 语句部分查询(含主键查询)
3.2.1 创建游标(含主键查询)

>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.2.2 查询数据并导入游标(含主键查询)

>>> cur.execute('select * from user_student')
6


补充:
1) 这里以查询 user_student 表里到所有数据并导入 cur 游标为例
2) 这里查出的数据总共有 6 条

3.2.3 将游标里的数据导入到变量里(含主键查询)

>>> cs = cur.fetchall()

(补充:这里以将数据导入到 cs 变量里为例)

3.2.4 将游标里的数据以对象的形式显示出来(含主键查询)

>>> print(cs)
((1, 'zhangsan', 60, 1), (2, 'lisi', 80, 1), (3, 'wangwu', 90, 1), (4, 'zhaoliu', 70, 1), (5, 'xueer', 70, 2), (6, 'huangyi', 70, 2))

(补充:这里显示出来的是对象)

3.2.5 将游标里的数据以列表的形式显示出来(含主键查询)

>>> for c in cs:
...     print(c)
... 
(1, 'zhangsan', 60, 1)
(2, 'lisi', 80, 1)
(3, 'wangwu', 90, 1)
(4, 'zhaoliu', 70, 1)
(5, 'xueer', 70, 2)
(6, 'huangyi', 70, 2)

(补充:这里打出来的是列表)

3.2.6 关闭游标(含主键查询)

>>> cur.close()

(补充:这里以关闭 cur 游标为例)

3.3 Django SQL 语句部分查询(不包含主键)
3.3.1 创建游标(不包含主键)

>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.3.2 查询数据并导入游标(不包含主键)

>>> cur.execute('select sname,score from user_student')
6


补充:
1) 这里以查询 user_student 表里 sname 字段和 socre 字段的所有数据并导入 cur 游标为例
2) 这里查出的数据总共有 6 条

3.3.3 将游标里的数据导入到变量里(不包含主键)

>>> cs = cur.fetchall()

(补充:这里以将数据导入到 cs 变量里为例)

3.3.4 将游标里的数据以对象的形式显示出来(不包含主键)

>>> print(cs)
(('zhangsan', 60), ('lisi', 80), ('wangwu', 90), ('zhaoliu', 70), ('xueer', 70), ('huangyi', 70))

(补充:这里显示出来的是对象)

3.2.5 将游标里的数据以列表的形式显示出来(不包含主键)

>>> for c in cs:
...     print(c)
... 
('zhangsan', 60)
('lisi', 80)
('wangwu', 90)
('zhaoliu', 70)
('xueer', 70)
('huangyi', 70)

(补充:这里显示出来的是列表)

3.2.5 关闭游标(不包含主键)

>>> cur.close()

(补充:这里以关闭 cur 游标为例)

3.3 Django SQL 语句部分查询(只查询一条数据)
3.3.1 创建游标(只查询一条数据)

>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.3.2 查询数据并导入游标(只查询一条数据)

>>> cur.execute('select * from user_clazz where id=1')
1


补充:
1) 这里以查询 user_clazz 表里 id 字段的值为 1 为例
2) 这里查出的数据总共有 1 条

3.3.4 将游标里的数据以对象的形式显示出来(只查询一条数据)

>>> cur.fetchone()
(1, 'Class1')

(补充:这里显示出来的是列表)

3.2.5 关闭游标(只查询一条数据)

>>> cur.close()

(补充:这里以关闭 cur 游标为例)