对象关系映射(Object Relational Mapping,简称 ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM 是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中,它实现了数据模型与数据库的解耦,即数据模型的设计不须要依赖于特定的数据库,经过简单的配置就能够轻松更换数据库,这极大的减轻了开发人员的工做量,不须要面对因数据库变动而致使的无效劳动。python
sql中的表 CREATE TABLE employee( id INT PRIMARY KEY auto_increment , name VARCHAR (20), gender BIT default 1, birthday DATA , department VARCHAR (20), salary DECIMAL (8,2) unsigned, ); 添加一条表纪录: INSERT employee(name, gender, birthday, salary, department) VALUES("alex", 1, "1985-12-12", 8000, "保洁部"); 查询一条表纪录: SELECT * FROM employee WHERE age=24; 更新一条表纪录: UPDATE employee SET birthday="1989-10-24" WHERE id=1; 删除一条表纪录: DELETE FROM employee WHERE name="alex"
# python的类 class Employee(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) gender = models.BooleanField() birthday = models.DateField() department = models.CharField(max_length=32) salary = models.DecimalField(max_digits=8,decimal_places=2) # 添加一条表纪录: emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保洁部") emp.save() # 查询一条表纪录: Employee.objects.filter(age=24) # 更新一条表纪录: Employee.objects.filter(id=1).update(birthday="1989-10-24") # 删除一条表纪录: Employee.objects.filter(name="alex").delete()
类 —— 表 类属性 —— 表字段 类对象 —— 表记录
建立名为 app01 的 app,在 app01 下的 models.py 中建立模型mysql
class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=20) price = models.DecimalField(max_digits=5, decimal_places=2) pub_data = models.DateTimeField() publish = models.CharField(max_length=32)
每一个字段有一些特有的参数,例如,CharField 须要 max_length 参数来指定数据库字段的大小。还有一些适用于全部字段的通用参数。 这些参数在文档中有详细定义,这里只简单介绍一些最经常使用的:git
AutoField - int自增列,必须填入参数 primary_key=True BooleanField - 布尔值类型 CharField - 字符类型,必须提供 max_length 参数,max_length表示字符长度 TextField - 文本类型 EmailField - Django Admin 以及 ModelForm 中提供验证机制 ImageField - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage width_field=None 上传图片的高度保存的数据库字段名(字符串) height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField - 日期格式 YYYY-MM-DD TimeField - 时间格式 HH:MM[:ss[.uuuuuu]] FloatField - 浮点型 DecimalField - 10进制小数 - 参数: max_digits 小数总长度 decimal_places 小数位长度
一、null 若是为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False. 二、blank 若是为True,该字段容许不填。默认为False。 要注意,这与 null 不一样。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。 若是一个字段的blank=True,表单的验证将容许该字段是空值。若是字段的blank=False,该字段就是必填的。 三、default 字段的默认值。能够是一个值或者可调用对象。若是可调用 ,每有新对象被建立它都会被调用。 四、primary_key 若是为True,那么这个字段就是模型的主键。若是没有指定任何一个字段的 primary_key=True, Django就会自动添加一个 IntegerField 字段作为主键, 因此除非想覆盖默认的主键行为,不然不必设置任何一个字段的primary_key=True。 五、unique 若是该值设置为 True, 这个数据字段的值在整张表中必须是惟一的 六、choices 由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 若是设置了choices ,默认的表单将是一个选择框而不是标准的文本框,并且这个选择框的选项就是choices中的选项。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'bms', # 要链接的数据库,链接前须要建立好 'USER': 'root', # 链接数据库的用户名 'PASSWORD': '000000', # 链接数据库的密码 'HOST': '127.0.0.1', # 链接主机,默认本级 'PORT': 3306, # 端口 默认3306 } }
注意一:NAME 即数据库的名字,在 mysql 链接前该数据库必须已经建立,而上面的 sqlite 数据库下的 db.sqlite3 则是项目自动建立。 USER 和 PASSWORD 分别是数据库的用户名和密码。设置完后,在启动 Django 项目前,须要激活 mysql。而后启动项目,会报错:no module named MySQLdb 。这是由于 django 默认导入的驱动是 MySQLdb,但是 MySQLdb 对于 Python3 有很大问题,所以使用驱动 PyMySQL。因此,须要找到项目名文件下的 __init__.py
,在里面写入:sql
import pymysql pymysql.install_as_MySQLdb()
注意二:确保配置文件中的 INSTALLED_APPS 中写入了建立的 app 名称数据库
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', ]
django 会把 settings 中的 INSTALLED_APPS 的每个应用中 models 对应的类建立成数据库中的表,在当前环境的项目目录下执行两个命令:django
python manage.py makemigrations python manage.py migrate
# create方法的返回值book_obj就是插入Book表中的这本书的记录对象 book_obj = Book.objects.create(title="图解HTTP", price=49, pub_date="2014-11-12", publish="人民邮电出版社")
book_obj = Book(title="图解HTTP", price=49, pub_date="2014-11-12", publish="人民邮电出版社") book_obj.save()
为了方便查询,在此以前已添加多条记录api
all() 查询全部结果 filter(**kwargs) 它包含了与所给筛选条件相匹配的对象 get(**kwargs) 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,若是符合筛选条件的对象超过一个或者没有都会抛出错误。 exclude(**kwargs) 它包含了与所给筛选条件不匹配的对象 order_by(*field) 对查询结果排序 reverse() 对查询结果反向排序 count() 返回数据库中匹配查询(QuerySet)的对象数量。 first() 返回第一条记录 last() 返回最后一条记录 exists() 若是QuerySet包含数据,就返回True,不然返回False values(*field) 返回一个ValueQuerySet,一个特殊的QuerySet,运行后获得的并非一系列model的实例化对象,而是一个可迭代的字典序列 values_list(*field) 它与values()很是类似,它返回的是一个元组序列,values返回的是一个字典序列 distinct() 从返回结果中剔除重复纪录
def addbook(request): # 添加表记录 # book = Book.objects.create(title="图解HTTP", price=49, pub_date="2014-11-12", publish="人民邮电出版社") # 查询表记录 # 一、all:返回一个QuerySet对象 # book_list = Book.objects.all() # print(book_list[0].title) # 图解HTTP # print(book_list) # <QuerySet [<Book: Book object>]> # 查询全部书籍名 # for obj in book_list: # print(obj.title) # 二、first/last:调用者是QuerySet对象,返回值是对象 # book = Book.objects.all().first() # book_2 = Book.objects.all().last() # print(book) # print(book2) # 三、filter:返回值是QuerySet对象(至关于where语句),能够加多个过滤条件 # book = Book.objects.filter(title='图解TCP/IP').first() # print(book) # 四、get:有且只有一个查询结果才有意义,返回值是一个对象 # 没有这个查询结果会报错 # book = Book.objects.get(title='Python源码剖析') # print(book) # 五、exclude:除了查询以外的,返回值也是QuerySet # ret = Book.objects.exclude(title='图解HTTP') # print(ret) # 六、order_by:默认升序,加个-就是降序。能够有多个过滤条件,调用者是QuerySet,返回值也是QuerySet # book_list = Book.objects.all().order_by('nid') # book_list_2 = Book.objects.all().order_by('-id', 'price') # print(book_list) # 七、count:调用者是QuerySet,返回值是int # ret = Book.objects.all().count() # print(ret) # 八、exists:判断是是否有值,不能传参数 # ret = Book.objects.all().exists() # print(ret) # 九、values:调用是QuerySet,返回值也是QuerySet # ret = Book.objects.values('price') # print(ret) # 十、value_list:调用是QuerySet,返回值也是QuerySet # ret = Book.objects.all().values_list('price', 'title') # print(ret) # 十一、distinct:调用是QuerySet,返回值也是QuerySet # ret = Book.objects.all().values('title').distinct() # print(ret) return HttpResponse('OK')
# 查询价格大于50的书的名字 # ret = Book.objects.filter(price__gt=50).values('title') # print(ret) # 查询大于40小于50的书 # ret = Book.objects.filter(price__gt=40, price__lt=50) # print(ret) # 查询以“图解”开头的书的名字 # ret = Book.objects.filter(title__startswith='图解').values('title') # print(ret) # 查询包含‘Python’的书 # ret = Book.objects.filter(title__contains='Python').values('title') # print(ret) # icontains 不区分大小写 # 价格在69,89,100中的 # ret = Book.objects.filter(price__in=[69, 89, 100]).values('title') # print(ret) # 出版日期在2016年的 # ret = Book.objects.filter(pub_date__year=2016) # print(ret)
删除方法就是 delete,它运行时当即删除对象而不返回任何值。例如:session
model_obj.delete()
也能够一次性删除多个对象。每一个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中全部的对象。例如,下面的代码将删除 pub_date 是 2005 年的 Entry 对象:app
Entry.objects.filter(pub_date__year=2005).delete()
在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:设计
b = Blog.objects.get(pk=1) # This will delete the Blog and all of its Entry objects. b.delete()
要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 自己。这是一种保护机制,是为了不意外地调用 Entry.objects.delete() 方法致使全部的记录被误删除。若是确认要删除全部的对象,那么必须显式地调用:
Entry.objects.all().delete()
若是不想级联删除,能够设置为:
pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)
Book.objects.filter(title__startswith="Py").update(price=120)
此外,update 方法对于任何结果集(QuerySet)均有效,这意味着能够同时更新多条记录 update 方法会返回一个整型数值,表示受影响的记录条数。
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled15.settings") import django django.setup() from app01 import models books = models.Book.objects.all() print(books)
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }