文章目录
介绍
Django 简单项目构建流程
软件架构
- django 2.1.5
- python 3.7
- windows 10
安装教程
- cd bookManage
- pip install -r requirement.txt
- cd bookManage
- python manage.py runserver
项目构建流程
1. 创建项目
django-admin startproject bookManager
2. 创建应用
python manager.py startapp book
3. 配置解释器
# 进入指定虚拟环境
which python3(which python)
# python3
/home/python/.virtualenvs/py3_django/bin/python3
# python2
/home/python/.virtualenvs/py_django/bin/python
4. 安装应用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#添加子应用
'book.apps.BookConfig'
]
5. 本地化
#设置中文
LANGUAGE_CODE = 'zh-Hans'
#亚洲上海时区
TIME_ZONE = 'Asia/Shanghai'
6.模板路径
在应用同级目录下,创建 templates 模板文件夹
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
7. 项目中匹配urls
正则 : 路径只要不是admin/就算匹配成功。并包含到应用中的urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path(r'book/', include('book.urls')),
]
8. 应用中匹配urls.py
- 应用中创建urls.py
- 正则 : 路径中包含booklist/,就调用视图中对应的bookList函数
from django.urls import path
from . import views
urlpatterns = [
# 匹配书籍列表信息的URL,调用对应的bookList视图
path(r'booklist/',views.bookList)
]
9.准备视图
# 定义视图:提供书籍列表信息
def bookList(request):
return HttpResponse('Hello world!')
10. 开启服务器, 测试项目
# 进入项目文件中, 开启项目对应的服务器
python manage.py runserver
# 浏览器中输入网址
http://127.0.0.1:8000/book/booklist/
11. 数据库配置
在 settings 中配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'NAME': 'book', # 数据库名
'USER': 'xxx', # 用户名
'PASSWORD': 'xxx', # 密码
'HOST': 'localhost', # 主机
'PORT': '3306', # 端口
}
}
12. 创建模型类
在book/models.py中,创建BookInfo和PeopleInfo模型类:
# 准备书籍列表信息的模型类
class BookInfo(models.Model):
# 创建字段,字段类型...
name = models.CharField(max_length=20, verbose_name='名称')
pub_date = models.DateField(verbose_name='发布日期', null=True)
readcount = models.IntegerField(default=0, verbose_name='阅读量')
commentcount = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'bookinfo' # 指明数据库表名
verbose_name = '图书' # 在admin站点中显示的名称
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.name
# 准备人物列表信息的模型类
class PeopleInfo(models.Model):
GENDER_CHOICES = (
(0, 'male'),
(1, 'female')
)
name = models.CharField(max_length=20, verbose_name='名称')
gender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
description = models.CharField(max_length=200, null=True, verbose_name='描述信息')
book = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书') # 外键
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'peopleinfo'
verbose_name = '人物信息'
def __str__(self):
return self.name
13. 迁移数据库
python manage.py makemigrations
python manage.py migrate
完成后连接mysql, 查看数据库是否创建成功
mysql -u USERNAME -p
PASSWORD
注:
USERNAME 是用户名
PASSWORD 是密码
我们将此类添加到工程settings.py中的INSTALLED_APPS列表中,表明注册安装具备此配置属性的应用。
-
AppConfig.name属性表示这个配置类是加载到哪个应用的,每个配置类必须包含此属性,默认自动生成。
-
AppConfig.verbose_name属性用于设置该应用的直观可读的名字,此名字在Django提供的Admin管理站点中会显示,如
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'book'
verbose_name = '图书管理'
数据库操作
1. 增加
- .save()
>>> from book.models import BookInfo,PeopleInfo
>>> book = BookInfo(
... name='python入门',
... pub_date='2010-1-1'
... )
>>> book.save()
>>> book
<BookInfo: python 从入门到放弃>
- create()
>>> PeopleInfo.objects.create(
... name='mgw',
... book=book
... )
<PeopleInfo: mgw>
2. 修改
- save()
>>> person = PeopleInfo.objects.get(name='mgw')
>>> person.name = 'mgw2168'
>>> person.save()
>>> person
<PeopleInfo: mgw2168>
- update()
>>> PeopleInfo.objects.filter(name='mgw').update(name='mgw2168')
1
3. 删除
- 模型类对象.delete
>>> person = PeopleInfo.objects.get(name='mgw')
>>> person.delete()
(1, {'book.PeopleInfo': 1})
- 模型类.objects.filter().delete()
>>> BookInfo.objects.filter(name='python 从入门到放弃').delete()
(1, {'book.BookInfo': 1, 'book.PeopleInfo': 0})
查询
1. 基本查询
get 查询单一结果, 若不存在, 会抛出
模型类.DoesNotExist
异常
all 查询锁哥结果
count 查询结果数量
2. 过滤查询
filter 过滤符合条件的多个结果
exclude 排除掉符合条件剩下的结果
get 过滤单一结果
# 过滤查询表达式
属性名称__比较运算符=值
1)相等
exact:表示判等。
例:查询编号为1的图书
BookInfo.objects.filter(id__exact=1)
等价于
BookInfo.objects.filter(id=1)
2)模糊查询
contains:是否包含。
说明:如果要包含%无需转义,直接写即可。
例:查询书名包含’传’的图书。
BookInfo.objects.filter(name__contains='传')
<QuerySet [<BookInfo: 射雕英雄传>]>
startswith,endswith:以指定值开头或结尾。
以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.
3) 空查询
isnull:是否为null。
4) 范围查询
in:是否包含在范围内。
5)比较查询
gt大于 (greater then)
gte大于等于 (greater then equal)
lt小于 (less then)
lte小于等于 (less then equal)
不等于的运算符,使用exclude()过滤器。
6)日期查询
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。
F和Q对象
F对象
之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中。
语法: F(属性名)
例:查询阅读量大于等于评论量的图书。
>>> from django.db.models import F
>>> BookInfo.objects.filter(readcount__gt=F('commentcount'))
<QuerySet [<BookInfo: 雪山飞狐>]>
可以在F对象上使用算数运算。
>>> BookInfo.objects.filter(readcount__gt=F('commentcount')*2)
<QuerySet [<BookInfo: 雪山飞狐>]>
Q对象
多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字。
例:查询阅读量大于20,并且编号小于3的图书。
>>> BookInfo.objects.filter(readcount__gt=20,id__lt=3)
<QuerySet [<BookInfo: 天龙八部>]>
或者
>>> BookInfo.objects.filter(readcount__gt=20).filter(id__lt=3)
<QuerySet [<BookInfo: 天龙八部>]>
如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符,Q对象被义在django.db.models中。
语法:Q(属性名__运算符=值)
例:查询阅读量大于20的图书,改写为Q对象如下。
BookInfo.objects.filter(Q(readcount__gt=20))
Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。
例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
>>> BookInfo.objects.filter(Q(readcount__gt=20)|Q(id__lt=3))
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>]>
Q对象前可以使用~操作符,表示非not。
例:查询编号不等于3的图书。
>>> BookInfo.objects.filter(~Q(id=3))
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>]>
聚合函数和排序函数
聚合函数
使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg平均,Count数量,Max最大,Min最小,Sum求和,被定义在django.db.models中。
例:查询图书的总阅读量。
>>> from django.db.models import Sum
>>> BookInfo.objects.aggregate(Sum('readcount'))
{'readcount__sum': 126}
注意aggregate的返回值是一个字典类型,格式如下:
{'属性名__聚合类小写':值}
如:{'readcount__sum': 126}
使用count时一般不使用aggregate()过滤器。
例:查询图书总数。
BookInfo.objects.count()
注意count函数的返回值是一个数字。
排序
使用order_by对结果进行排序
查询集
- all():返回所有数据。
- filter():返回满足条件的数据。
- exclude():返回满足条件之外的数据。
- order_by():对结果进行排序。
- exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。
从SQL的角度讲,查询集与select语句等价,过滤器像where、limit、order by子句。
两大特性
- 惰性查询
创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用
例如,当执行如下语句时,并未进行数据库查询,只是创建了一个查询集books
books = BookInfo.objects.all()
继续执行遍历迭代操作后,才真正的进行了数据库的查询
for book in books:
print(book.name)
- 缓存
使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。
- 限制查询集
可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。
注意: 部支持负数索引
对查询集进行切片后返回一个新的查询集,不会立即执行查询。
如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()如果没有数据引发DoesNotExist异常。