6 单表操作

一、操作单表之前的简单配置

1 创建表

  在 Django 项目下对应的 app 目录中的 models.py 文件下创建模型

(1)创建模型

from django.db import models

class Book(models.Model):
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish_date=models.DateField(default='1999-11-27')
    publish=models.ForeignKey(to=Publish,to_field='id')

 

2 在 settings 中选择并设置需要的数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '连接的数据库名称',
        'USER': '账户名称',
        'PASSWORD': '账户密码',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'ATOMIC_REQUEST': True,
        'OPTIONS': {
            "init_command": "SET storage_engine=MyISAM",
        }
    }
}
'''
'NAME':要连接的数据库,连接前需要创建好
'USER':连接数据库的用户名
'PASSWORD':连接数据库的密码
'HOST':连接主机,默认本机
'PORT':端口 默认3306
'ATOMIC_REQUEST': True,
设置为True统一个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败)。
是全局性的配置, 如果要对某个http请求放水(然后自定义事务),可以用non_atomic_requests修饰器 
'OPTIONS': {
             "init_command": "SET storage_engine=MyISAM",
            }
设置创建表的存储引擎为MyISAM,INNODB
'''
1 在 mysql 连接前该数据库必须已经创建,而上面的 sqlite 数据库下的 db.sqlite3 则是项目自动创建 USER 和 PASSWORD 分别是数据库的用户名和密码。设置完后,再启动我们的Django 项目前,我们需要激活我们的 mysql 。然后,启动项目,会报错:no module named MySQLdb 。这是因为 django 默认你导入的驱动是 MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的__init__,在里面写入:
2 
3 import pymysql
4 pymysql.install_as_MySQLdb()
注意

3 执行数据库迁移命令即可创建出对应的表

(1)方式一:

1 初始化数据,此时还未开始创建或者更新数据
python manage.py makemigrations

2 开始创建
python manage.py migrate

(2)方式二:

进入上述图片的操作之后,会进入一个类似于命令行的窗口,直接执行命令 (1)makemigrations 和 (2)migrate 两条命令后即可创建表格

4 INSTALLED_APPS 确保配置文件中写入创建的 app 名称

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    # app01,这个不是建议写法
]

 

注意:

MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:

通过查找路径C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql
这个路径里的文件把

if version < (1, 3, 3):
     raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
解决方法

 

二、单表操作

1 字段的增加、删除

(1)删除:直接注释掉字段,执行数据库迁移命令即可

(2)新增字段:在 models.py 类里直接新增字段,直接执行数据库迁移命令会提示输入默认值,此时需要设置

publish = models.CharField(max_length=32,default='默认值',null=True)

注意:

  1 数据库迁移记录都在 app01下的migrations里
  2 使用showmigrations命令可以查看没有执行migrate的文件
  3  makemigrations是生成一个文件,migrate是将更改提交到数据量

2 添加表记录

(1)方式一:

# create 方法的返回值 book_obj 就是插入 book 表中的 Django 这本书籍纪录对象
book_obj=Book.objects.create(name="Django",state=True,price=998,publish="未知出版社",pub_date="9999-99-99")

(2)方式二:

book_obj=Book(name="Django",state=True,price=998,publish="未知出版社",pub_date="9999-99-99")
book_obj.save()

3 查询表记录的常用 API

 

(1)  all(): 查询所有结果  
(2)  filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
(3)  get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 
(4)  exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
(5)  order_by(*field): 对查询结果排序,默认是从大到小排序;字符串前加 - 号('-id'),表示从小到大排序
(6)  reverse(): 对查询结果反向排序  
(7)  count(): 返回数据库中匹配查询(QuerySet)的对象数量。 
(8)  first(): 返回第一条记录
(9)  last(): 返回最后一条记录
(10) exists(): 如果QuerySet包含数据,就返回True,否则返回False
(11) values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model 的实例化对象,而是一个可迭代的字典序列
(12) values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
(13) distinct(): 从返回结果中剔除重复纪录

 

 

1 book = Book.objects.all().gei(id="2")  # get 只能用来查询返回一条数据的情况,记录过多或者过少都会产生报错
2 book_dic = Book.objects.all().values('name','price')  # 返回一个类似字典的 QuerySet 对象,经过 first() 处理之后就不是对象了,可以通过循环来取值
3 book_tuple = Book.objects.all().values_list()  # 返回一个类似元组的 QruerySet 对象,可循环取值
4 reverse()  # 将查询结果反向排序,但是必须在 order_by() 之后使用才可以生效
5 1️⃣ Book.objects.all().order_by('price','publish_date').reverse()
6 2️⃣ Book.objects.all().order_by('-price','publish_date')
7 1️⃣ 和 2️⃣ 结果是相同的
Notice

4 双下划线的模糊查询

 

 

 1 Book.objects.filter(price__in=[100,200,300])
 2 Book.objects.filter(price__gt=100)    # 大于100
 3 Book.objects.filter(price__lt=100)
 4 Book.objects.filter(price__gte=100)   # 大于等于100
 5 Book.objects.filter(price__lte=100)
 6 Book.objects.filter(price__range=[100,200])  # 在 100 至 200 之间,包括首尾
 7 Book.objects.filter(name__contains="Django")
 8 Book.objects.filter(name__icontains="Django")  # 忽略大小写,由于版本原因,结果可能不一样
 9 Book.objects.filter(name__startswith="D")
10 Book.objects.filter(publish_date__year=9999)  # 出版日期的年份,对应的还有月份日期等

5 删除记录

1️⃣ Book.objects.filter(name="Django").first().delete() # 注意是没有返回值的
2️⃣ QuerySet.delete()
1️⃣ 和 2️⃣ 的结果是一样的

(1,{'app01.Book':1})  # 各个参数的说明
第一个 1 是:总体影响的行数
app01.Book:哪个表的记录
第二个 1 是:影响表的记录

delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用
Book.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:
Book.objects.all().delete()
若不想级联删除,可以设置为:
pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)
级联删除参数设置
在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:
b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()
Notice

6 更新表记录

update() 方法对于任何结果集(QuerySet)均有效,Manage 对象不可调用,意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。

Book.objects.filter(name__startswith="D").update(price=999)

 

三、在 Python 脚本中调用 Django 环境(了解)

import os
if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Django名称.settings")
    import django
    django.setup()

    from app01 import models

    books = models.Book.objects.all()
    print(books)

注意:

Django 名称可以在 manage.py 中查看或者核对

 

四、Django 中打印 SQL 语句

方式一:
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

方式二:
obj = Book.objects.all().filter(pk=1)
print(obj.query)

 

posted @ 2018-09-16 21:38  Smart1san  阅读(212)  评论(0编辑  收藏  举报