一、虚拟环境
1.1 安装虚拟环境
# 创建虚拟环境文件夹
d:\>mkdir virtualenv
d:\>cd virtualenv
d:\virtualenv>pip install virtualenv
# 虚拟环境-p指向python解释器,创建文件夹env-py3.6
d:\virtualenv>virtualenv -p D:\学习\编程\Python\python\python.exe env-py3.6
- 激活虚拟环境
# 进入Scripts目录激活虚拟环境
d:\virtualenv>cd env-py3.6\Scripts
d:\virtualenv\env-py3.6\Scripts>activate
- 退出虚拟环境
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>deactivate.bat
1.2 安装Django
# 虚拟环境下安装Django
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>pip install django
# 创建Django项目
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>django-admin startproject myshop
二、路由
2.1 路由基本配置
from django.contrib import admin
from django.urls import path
from . imporot views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index, name='index'),
# path(路由, 视图函数, 别名)
]
2.2 带 URL参数的路由
urlpatterns = [
path('app2/show/<int:id>/', views.show),
# <参数数据类型: 参数名称>
]
参数数据类型 | 说明 |
---|---|
str | 任意非空字符,不包含“/”,默认类型 |
int | 匹配0和正整数 |
slug | 匹配任何ASCII字符、连接符和下划线 |
uuid | 匹配一个UUID格式的字符串,该对象必须包括"-",所有字母必须小写。 |
2.3 re_path()方法正则匹配复杂路由
正则表达式 | 说明 |
---|---|
. | 匹配任意单个字符 |
\d | 匹配任意一个数字 |
\w | 匹配字母、数字、正划线 |
* | 匹配0个或多个字符 |
[a-z] | 匹配a~z中任意一个小写字符 |
{1,5} | 匹配1~5个字符 |
urlpatterns = [
re_path(r'app/page/(?P<page>\d+)&key=(?P<key>\w+)', views.article_page,name='article_page'),
# page:匹配数字
# key:匹配字母、数字、正划线
]
2.4 反向解析路由
urlpatterns = [
path('app/url_reverse', views.url_erverse, name='app_url_reverse'),
]
# 视图函数使用反向解析
from django.urls import reverse
def url_reverse(request):
return render(reverse('app_url_reverse'))
# 在模板使用反向解析
<div>
{% url 'app_url_reverse' %}
</div>
2.5 视图函数
2.5.1 HttpRequest对象
属性/方法 | 含义 |
---|---|
path | 字符串,表示请求页面的路径,不包含域名 |
method | 字符串,表示页面的请求方法,常用值包括“GET”和“POST”。必须使用大写方式 |
encoding | 字符串,表示提交的数据的编码方式。一般默认为UTF-8编码方式 |
GET | 字典类型,包含GET请求方法中的有所参数 |
POST | 字典类型,包含POST请求方法中的有所参数 |
FILES | 字典类型,包含上传文件的信息 |
COOKIES | 字典类型,包含所有的Cookies对象 |
session | 字典类型,表示当前的会话 |
META | 字典类型,包含所有的HTTP头部信息,如HTTP_USER_AGENT(客户端Agent信息)、REMOTE_ADDR(客户端的IP地址)等 |
2.5.2 HttpResponse对象
属性 | 含义 |
---|---|
content | 返回的内容 |
status_code | 返回的HTTP响应状态码 |
content-type | 返回的数据的MIME类型,默认为text/html |
- 常用状态码status_code
状态码 | 含义 |
---|---|
200 | 状态成功 |
301 | 永久重定向,Location属性的值为当前URL |
302 | 临时重定向,Location属性的值为新的URL |
404 | URL未发现,不存在 |
500 | 内部服务器错误 |
502 | 网关错误 |
503 | 服务不可用 |
2.5.3 视图处理函数的使用
-
render()
render(request, template_name,content=None,content_typw=None,status=None,using=None)
- request: 传递给视图函数的所有请求,其实就是视图函数的参数request
- template_name:渲染的模板文件,一般放在templates目录下
- content:数据格式为字典类型,保存要传递到HTML文件中的变量
- content_type:用于生成文档的MIME类型。默认为text/html
- status:表示响应的状态代码,默认为200
- using:设置模板引擎,用于解析模板文件
-
redirect():实现页面重定向
三、DJango模板
3.1 变量
- {{ var }}:直接调用变量
- {{ lst.0 }}:根据索引调用列表
- {{ dicts.name }}:根据key调用字典
3.2 模板标签
模板标签 | 描述 |
---|---|
{% if %} {% endif %} | 条件判断模板标签 |
{% for foo in %} {% endfor %} | 循环模板标签 |
{% url '' %} | 路由配置地址标签 |
{% extends 'xx' %} | 模板继承标签,从xx模板继承 |
{% load tz %} | 加载相关内存 |
{% static %} | 静态资源 |
{% block %} {% endblock %} | 一组占位符标签,需要重写模板 |
{% csrf_token %} | 用来防护跨站请求伪造攻击 |
{% include 页面 %} | 包含一个HTML页面 |
- 循环模板标签
变量 | 含义 |
---|---|
forloop.counter | 表示当前循环的索引,从1开始计数 |
forloop.counter0 | 表示当前循环的索引,从0开始计数 |
forloop.revcounter | 表示循环中剩余元素的数量。在进行第1次循环时,forloop.revcounter的值是循环的序列中元素的总数。在进行最后一次循环时,forloop.revcounter的值是1 |
forloop.revcounter0 | 表示循环中剩余元素的数量。在进行第1次循环时,forloop.revcounter的值是循环的序列中元素的总数。在进行最后一次循环时,forloop.revcounter的值是0 |
forloop.first | 表示是否是第1次循环 |
forloop.last | 表示是否是最后一次循环 |
forloop.parentloop | 在嵌套循环中,获取上层的for循环 |
3.3.模板过滤器
模板过滤器 | 格式 | 描述 |
---|---|---|
safe | {{ name|safe }} | 关闭HTML标签和JavaScript脚本的语法标签的自动转义功能 |
length | {{ name|length }} | 获取模板变量的长度 |
default | {{ name|default:"默认值" }} | 当变量的值为False时,显示默认值 |
date | {{ name|date:"Y-m-d G:i:s" }} | 格式化输出时间日期变量 |
upper | {{ name|upper }} | 将字符串转为大写 |
lower | {{ name|lower }} | 将字符串转为小写 |
slice | {{ name|slice:"2:4"}} | 以切片方式获取字符串中的一部分,和Python中切片语法一样 |
-
日期过滤器格式化
- Y表示年:格式为4位。y表示两位的年。
- m表示月:格式01、02、12等。
- d表示日:格式01、02等。
- j表示日:格式为1、2等。
- H表示二十四进制的"时",h表示十二进制的"时"。
- i表示分:值为0~59。
- s表示秒:值为0~59。
-
自定义过滤器
-
在应用下创建templatetags的包
-
在包下创建myfilter.py文件
-
编写自定义过滤器并注册
from django import template register = template.Library() @register.filter # 指明show_title函数是一个过滤器 def show_title(value, n): # value指的是文章标题 n指标题要显示的长度 if len(value) > n: return f'{value[0:n]}...' else: return value
- 模板调用过滤器
{% load show_title %}
-
四、使用数据库models
4.1 常用模型字段
模型字段 | 说明 | MySQL数据库对应的字段类型 |
---|---|---|
AutoField | 数据库中的自动增长类型,相当于ID自动增长的IntegerField类型字段 | Int类型 |
BooleanField | 一个真/假(true/false)的布尔类型字段 | Tinyint类型 |
CharField | 字符类型字段 | varChar类型 |
DateField | 日期字段 | Date类型 |
DateTimeField | 日期时间类型字段 | DateTime类型 |
IntergerField | 整数类型字段 | Int类型 |
TextField | 长文本类型字段 | Longtext类型 |
TimeField | 时间类型字段 | Time类型 |
FloatField | 浮点数类型字段 | Double类型 |
FileField | 文件类型字段 | varChar类型 |
ImageField | 图像类型字段 | varChar类型 |
DecimalField | 数值型类型字段 | Decimal类型 |
- 数字型字段DecimalField
- max_digits:数字允许的最在位数
- decimal_places:小数的最大位数
- 时间日期类型字段
- auto_now_add:默认为False,设置为True自动添加创建时间
- auto_now:默认为False,设置为True自动添加修改时间
4.2 常用字段参数
字段参数 | 含义 |
---|---|
verbose_name | 设置字段的显示名称 |
primary_key | 设置字段为主键 |
editable | 是否可以编辑,一般用于Admin后台 |
max_length | 设置字段的最大长度 |
blank | 若为True,则该字段允许为空值,在数据库中表现为空字符串。默认为False |
null | 若为True,则该字段允许为空值,在数据库中表现为null。默认为False |
default | 设置字段的默认值 |
choices | 设置字段的可选值 |
db_column | 设置表中的列名称,如果不设置,则将字段名作为列名称 |
db_index | 数据库中的字段是否可以建立索引 |
unique | 数据库中字段是否可以建立 唯一索引 |
error_messages | 自定义错误信息(字典类型) |
validators | 自定义错误验证(列表类型) |
4.3 Meta类
参数 | 含义 |
---|---|
abstract | 若为True,则该模型类为抽象类 |
db_table | 设置模型对象的数据表名称。若不设置,则默认设置数据表名称为"应用名+下划线+模型类名" |
managed | 默认为True.Django会管理数据表的生命周期,包括迁移等 |
ordering | 模型对象返回的记录结果集按照那个字段排序。一般如下设置:Ordering=["create_date"]:按照创建时间升序排序,Ordering=["-create_date"]:按照创建时间降序排列,Ordering=["-create_date","orderid"]:按照创建时间降序排列,再以订单编号升序排列 |
verbose_name | 模型类在后台管理中显示的名称,一般为中文 |
index_logether | 多个字段的联合索引 |
unique_together | 多个字段 的联合约束 |
# explame
class Meta:
managed=False # 不做数据迁移等操作
verbose_name='人员基本信息' # 显示信息
db_table = 'UerBaseInfo' # 设置数据库中的表名
4.4 模型中的关系
4.4.1 一对一关系OneToOneField()
-
参数表
参数 含义 to 要进行关联的模型名称 to_field 要进行关联的表的字段名称 on_delete 在删除关联表中的数据时使用的配置选项 - ondelete参数配置选项表
配置选项 含义 CASCADE 在删除基本信息表时一并删除扩展表的信息,即级联删除 PROTECT 在删除基本信息表时采用保护机制抛出错误,即不删除扩展表的内容 SET_NULL 只有当字段属性null=True时才将关联的内容置空 SET_DEFAULT 设置为默认值 SET 设置为指定的值 DO_NOTHING 删除基本信息表,对扩展表不做任何操作
4.4.2 一对多关系ForeignKey()
参数 | 含义 |
---|---|
to | 要进行关联的模型名称 |
to_field | 要进行关联的表的字段名称 |
on_delete | 在删除关联表中的数据时使用的配置选项 |
related_name=None | 在反向操作时使用的字段名,用于代替【表名_set】。如obj.表名 _set.all() |
related_query_name=None | 在反向操作时使用的连接前缀, 用于替换【表名】。如modles.UserGroup.objects.filter(表名_ 字段名=1).values('表名_ 字段名') |
db_constraint=True | 是否在数据库中创建外键约束 |
4.4.3 多对多关系
参数 | 含义 |
---|---|
to | 要进行关联的模型名称 |
db_constraint=True | 是否在数据库中创建外键约束 |
db_table=None | 默认创建的多对多关系表的表名 |
4.5 配置项目文件
- setting配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 配置为mysql
'NAME': 'shop-test', # 数据库名
'USER': 'root', # 数据库登录账户
'PASSWORD': '123456', # 登录密码
'HOST': 'localhost', # 数据库IP地址
'PORT': '3306', # 数据库端口号
# 取消外键约束
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
}
}
}
- 执行命令
# 生成迁移文件
python manage.py makemigrations
# 执行迁移
python manage.py migrate
4.5.1 配置日志打印输出
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level': 'DEBUG',
},
}
}
4.6 ORM
- all()方法 :获取模型的QuerySet对象,即获取所有的数据。
- filter()方法:返回一个QuerySet对象,如果滑获取数据,则返回空的QuerySet对象。
模型类.objects.filter(字段=值)
- get()方法:查询数据表记录,以模型对象的形式返回符合要求的一条数据。当没有查询到结果或者超过一条记录,会出现错误提示。
- exclude()方法:该方法排除符合条件的数据,返回QuerySet对象。
模型类.objects.exclde(字段=值)
操作符 | 含义 | 具体使用 |
---|---|---|
__gt | 大于 | filter(age__gt=20) |
__gte | 大于等于 | filter(age__gte=20) |
__lt | 小于 | filter(age__lt=20) |
__lte | 小于等于 | filter(age__lte=20) |
__in | 在某个列表内 | filter(sex__in=[1,0]) |
__contains | 模糊匹配 | filter(username__contains='张') |
__year | 日期字段的年份 | filter(createdate__year=2022) |
__month | 日期字段的月份 | filter(createdate__month=10) |
__day | 日期字段的天数 | filter(createdate__day=2) |
- values()方法:提取指定需要的字段 。它返回一个QuerySet对象。
- distinct()方法:该方法用于去除重复数据。它返回一个QuerySet对象。
4.6.1 查询数据
- all()
- filter()
- get()
4.6.2 新增数据
- 使用save()方法新增数据
from app import models
depart=models.DepartInfo(departname="技术部")
depart.save()
- 使用create()方法新增
UserBaseInfo.objects.create(username="张三",password="123456")
4.6.3 更新数据
- 单条数据更新
one_user = UserExtraInfo.objects.get(id=1)
one_user.username="王五"
one_user.save()
- 多条数据更新
models.objects.update(status=1) # 所有用户状态更新为1
4.6.4 删除数据
- 删除单选数据
UserBasicInfo.objects.get(id=1).delete()
- 删除多选数据
UserBasicInfo.objects.filter(status=2).delete()
- 删除全部数据
UserBasicInfo.objects.all().delete()
4.6.5 操作关联表
-
一对一关联表操作
-
一对多关联表操作
-
多对多关联表操作
-
select_related()方法
cards = models.CardInfo.objects.select_related("user")
- prefetch_related()方法:同select_related()方法类似,用于解决“多对一”和“多对多”关系的查询问题。
skills = SkillInfo.objects.prefetch_related("user")
4.6.6 F()函数和Q()函数
- F()函数:用于实现数据表中字段 的各种运算操作。
from django.db.models import F
# 给所有用户+1000
users = UserExtraInfo.objects.all()
for user in users:
user.salary+=1000
user.save()
# 使用F增加效率
for user in users:
user.salary=F("salary")+100
user.save()
- Q()函数:用于对象进行多条件查询。
from django.db.models import Q
user = UserExtraInfo.objects.filter(Q(age__gt=30)&Q(salary__gt=5000))
4.7 执行原生SQL
-
Raw()方法返回RawQuerySet对象
django.db.models.Manager.raw(raw_query)
-
基本使用
UserExtraInfo.objects.raw("select * from userbaseinfo")
-
条件查询(带参数)
name="张三" sql='''select * from userextrainfo where username=%s''' users = UserExtraInfo.objects.raw(sql,[name])
-
-
游标方法
- 插入数据
from django.db import connection import django.utils.timezone as timezone cursor = connection.cursor() insertsql="insert into departinfo(departname,createdate) values(%s,%s)" data = ('总经办',timezone.now()) cursor.exectue(insertsql,data) cursor.close()
- 查询数据
from django.db import connection cursor = connection.cursor() cursor.exectue("select * from userextrainfo") row = cursor.fetchone() # 以元组方式返回一条记录 print(row) cursor.close()
- 更新数据
from django.db import connection cursor = connection.cursor() try: updatesql = 'update departinfo set departname=%s where id=%s' data=('销售部', 2) cursor.execute(updatesql,data) rowcount=cursor.rowcount # 影响行数 connection.commit() except: connection.rollback() # 返回参数为影响行数
- 删除数据
cursor=connection.cursor() sql="delete from departinfo where departname = %s" data=["总经办"] cursor.execute(sql,data) cursor.close()
4.8 事务处理
4.8.1 装饰器方式
from django.db import transaction @transaction.atomic # 装饰器 def trans(request): # 开启事务 save_id=transaction.savepoint() try: # 代码操作 1 # 代码操作 2 # 提交从保存点以当前状态的所有数据库事务操作 transaction.savepoint_commit(save_id) except: # 事务回滚,回滚到保存点 transaction.savepoint_rollback(save_id)
4.8.2 with语句方式
def trans_with(request): with transaction.atomic(): # with语句 # 开启事务 save_id = transaction.savepoint() try: # 代码操作 1 # 代码操作 2 # 提交从保存点以当前状态的所有数据库事务操作 transaction.savepoint_commit(save_id) except: # 事务回滚,回滚到保存点 transaction.savepoint_rollback(save_id)