- 创建项目
django-admin startproject django_model
- 创建应用
python manage.py startapp model
- 配置应用 model, 编辑 django_model/settings.py 文件:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'model',
]
- 配置Mysql数据库:编辑 django_model/settings.py 文件, 内容如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # mysql数据库引擎
'NAME': 'my_model', # 数据库名字
'USER': 'root', # 用户名
'PASSWORD': 'fe_cow', # 密码
'HOST': 'localhost', # 主机
'PORT': '3306' # 端口
}
}
- 创建应用所需数据库表, 首先我们创建数据库:
create dababase my_model charset = utf8;
- 注意: 使用PyMysql数据库驱动,需要在 djangomodel/_init__.py 中增加如下代码:(python2不需要配置这项)
import pymysql
pymysql.install_as_MySQLdb()
- 定义模型
定义模型其实就是定义一个python类;一个模型类代表数据库中一张表,一个模型类的实例代表这个数据库表中的一条特定的记录
from django.db import models
class Publisher(models.Model):
"""出版社"""
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
country = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Author(models.Model):
"""作家"""
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
"""书"""
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author) # 书和作者是多对多的关系
publisher = models.ForeignKey(Publisher) # 书和出版者是多对一的关系
publication_date = models.DateField()
def __unicode__(self):
return self.title
- 定义完模型后,要执行数据库迁移操作:
先执行python manage.py makemigrations 在执行:python manage.py migrate
一张表中定义了多对多的关系,ORM会自动创建实现多对多关系的第三张表。
数据库的操作:
通过python shell 来演示数据库的操作。在终端切换到项目根目录下,输入命令python manage.py shell 进入shell操作环境。
增删改查
1 创建记录
方法一:实例化(调用save()方法之前,Django不会访问数据库;save()方法没有返回值)
>>> from apps.models import Author
>>> author = Author(last_name='fe_cow')
>>> author.save()
>>> print author
fe_cow
方法二:create() (只用一条语句创建并保存一个对象,使用create()方法。)
>>> Author.objects.create(first_name='fe',last_name='cow', email='[email protected]')
方法三:get_or_create(), 这种方法可以防止重复(速度稍慢,因为会先查数据库), 它返回一个元组。创建成功返回True,失败的话False,不执行创建。
>>> author = Author.objects.get_or_create(last_name='fe_cow')
>>> print author
(<Author: fe_cow>, False) # False:说明已经重复 创建失败
>>> author = Author.objects.get_or_create(last_name='cu_cow')
>>> print author
(<Author: cu_cow>, True) # True: 创建成功
2 查询记录
方法一:查询所有对象 (all()方法返回包含数据库中所有对象的一个查询集。)
>>> author = Author.objects.all()
>>> print author
<QuerySet [<Author: fecow>, <Author: fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: cu_cow>]>
方法二:过滤查询 (filter()返回一个新的查询集,它包含满足查询参数的对象。)
>>> author = Author.objects.filter(last_name='cu_cow')
>>> print author
<QuerySet [<Author: cu_cow>]>
方法三:指定查询 (get查询只能返回一个对象,多了少了都会引发DoesNotExist 异常)
>>> author = Author.objects.get(id=1)
>>> print author
fecow
方法四:双下划线查询__;__contains:包含;__icontains不区分大小写;__regex:正则查询;__lt:小于xxx;__lte:小于等于xxx;__gt:大于xxx;__gte:大于等于xxx;__startswith(): 以xxx开头,;__istartswith():不区分大小写以xxx开头, __endswith():以xxx结尾;__iendswith():以xxx结尾不区分大小写
以上使用方法基本上都一致:对象.objects.filter(属性 __xxx) 例子如下:
>>> author = Author.objects.filter(id__gte=2)
>>> print author
<QuerySet [<Author: fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: cu_cow>]>
单独说一个特殊的__in 判断字段在列表内。通常用pk指主键,不限于id,适用更好。
>>> author_list = Author.objects.values_list('id', flat=True)
# 返回的是:<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
>>> Author.objects.filter(pk__in=author)
<QuerySet [<Author: fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: cu_cow>]>
方法五:first(), last()获取查询结果中单个对象
>>> Author.objects.filter(id__gte=2)
# 返回结果:QuerySet集合
<QuerySet [<Author: fe_cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: fe cow>, <Author: cu_cow>]>
>>> Author.objects.filter(id__gte=2).first()
# 返回结果:objects对象 而且返回第一个对象
<Author: fe_cow>
>>> Author.objects.filter(id__gte=2).last()
<Author: cu_cow>
# 返回结果:objects对象 而且返回的是最后一个对象
方法六:通过values查询
values('字段')用字典形式,返回的是指定字段的查询结果;
>>> Author.objects.values('last_name')
<QuerySet [{'last_name': u'fecow'}, {'last_name': u'fe_cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cow'}, {'last_name': u'cu_cow'}]>
# 返回字典列表;多个字段间以逗号分隔
values_list('字典'),返回的也是指定字段的查询结果
>>> Author.objects.values_list('last_name')
<QuerySet [(u'fecow',), (u'fe_cow',), (u'cow',), (u'cow',), (u'cow',), (u'cow',), (u'cu_cow',)]>
# 返回的是元组列表,多个字段也是用逗号分割
values_list('字段', flat=True) flat=True :之后返回的是值列表
>>> Author.objects.values_list('id', flat=True)
<QuerySet [1L, 2L, 3L, 4L, 5L, 6L, 7L]>
# 返回的是列表
方法六:exclude(**kwargs)反向过滤
>>> Author.objects.exclude(id__gt=2)
<QuerySet [<Author: fecow>, <Author: fe_cow>]>
# 取反
方法七:exists()
>>> Author.objects.filter(id=2).exists()
True
# QuerySet包含数据返回True
>>> Author.objects.filter(last_name='Au_cow').exists()
False
# QuerySet不包含数据返回False
3 修改记录
方法一:QuerySet.update('字段'='修改的值')
>>> Author.objects.filter(last_name='cu_cow').update(last_name='Ai_cow')
1L
# 修改的前提是先查找,然后调用update(field=val)方法,只有QuerySet集合对象才能调用该方法,也就是说通过get(), first(), last()获取的对象没有该方法。
方法二:对象赋值
>>> author_obj = Author.objects.filter(last_name='fe_cow').first()
>>> author_obj.last_name = 'Fe_cow'
>>> author_obj.save()
# 不推荐使用,效率低
4 删除记录
调用delete()方法 delete()方法支持QuerySet集合对象的删除,也支持单个对象的删除。
>>> Author.objects.filter(last_name='fe_cow').delete()
(1L, {u'apps.Book_authors': 0L, u'apps.Author': 1L})
# 默认就是级联删除,对应多对多的表也会删除
QuerySet
通过名字我们也能想到从数据库查出来的结果一般是一个集合,哪怕只有一个对象,也叫集合。
QuerySet特性
可以进行切片,也可以进行遍历。
>>> Author.objects.filter(id__gt=2)[:2] # 使用切片来获取
# <QuerySet [<Author: fe cow>, <Author: fe cow>]>
>>> authors = Author.objects.filter(id__gt=2) # 使用for循环来获取
>>> for author in authors:
... print author
# 打印结果如下
# fe cow
# fe cow
# fe cow
# fe cow
惰性机制: 只有使用QuerySet时,才会走数据库。像.all() filter()时,并不会真正执行数据库查询,只是翻译了SQL语句;当我们执行if xxx ,print xxx; for xxx in xxx:这些操作才会执行SQL语句,进行数据库查询。
缓存机制:每次执行了数据库查询后,会将结果放在QuerySet的缓存中,下次在使用QuerySet时, 不会走数据库,直接从缓存中拿取数据。比如:
>>> author = Author.objects.all() # 获取所有Author QuerySet中的 last_name
>>> for res in author:
... print res.last_name # Ai_cow cow
>>> Author.objects.create(last_name='COW',first_name='FE') # 接下来往数据库中插入一跳数据
>>>for res in author:
print res.last_name # Ai_cow cow # 发现,已经创建了新的数据,但是表里面没有这条数据
# 以上结果证明了QuerySet缓存的机制,新添加一条记录;打印结果没有发生改变,说明他不会重新走数据库,而是从缓存中获取数据。
>>> author = Author.objects.all() # 获取所有Author QuerySet中的 last_name
>>> for res in author:
... print res.last_name # Ai_cow cow COW
————————————————
版权声明:本文为CSDN博主「Fe_cow丿」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Fe_cow/article/details/80669146