python -m venv djenv # 1.创建虚拟环境,djenv名称随意
#
source djenv/bin/activate #Mac 进入激活虚拟环境
djenv\Scripts\activate-Windows #Windows 进入激活虚拟环境
pip install Django
pip show Django#查看版本
django-admin startproject 项目名
或者
python -m django startproject 项目名
cd 项目名
django-admin startapp app应用名
或者
python -m django startapp app应用名
或者
python manage.py startapp app应用名
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'sign', # app应用名
]
# [port] 为应用访问端口,可选,默认为8000端口(但酷狗音乐默认端口为 8000,因此我们最好指定端口)
python manage.py runserver [port]
1.Django视图
Django 视图的作用:用于接受Web请求并且返回Web响应的简单 Python 函 数。该函数一般定义在各自应用的 views.py 文件中。在视图函数中有两个重要 的对象:请求对象和响应对象。 下面是一个最简单的视图函数:
# 例:在demo/views.py 中
from django.http import HttpResponse
def index(request): #可写成req
return HttpResponse('我的第一个视图!Hello,World')
#render函数
def evnets(req):
event_list = Event.objects.all()
# 三个参数,第一个为request对象,第二个为模板名称,第三个为返回的数据(字典格式),.....
return render(req,'events.html',{'event_list': event_list})
2.Django路由
路由:就是请求向导,通俗点说就是用户请求的Url和视图的映射关系。
Django 的路由定义文件为:项目目录 /urls.py 文件。我们所有的路由配 置,都以数组的方式,定义在 urls.py 文件中,每个app应用下的/urls.py定义好之后,再汇总到项目下的 /urls.py
2.1路由分级
第一步:在各个应用的根目录下,创建 urls.py 文件(文件名可以自定义, 一般用 urls )
from django.urls import path
from app名 import views as sign_view #
urlpatterns = [
# 第一个参数:浏览器里的URL,第二个参数:应用里的函数名
path("events/", sign_view.evnets),
path("guest_detail//" , sign_view.guest_detail),
]
第二步:修改主路由,把其他应用的路由,通过include导入进来
from django.contrib import admin
from django.urls import path,include #1...导入include模块
#2...导入其他应用的urls模块
from 应用名 import urls as sign_urls
urlpatterns = [
path('admin/', admin.site.urls),
# 3...导入子路由 (参数1=父路由访问路径,参数2=导入子路由)
#第一个参数:浏览器中的更深一层url,第二个参数是应用名-别名
path("sign/", include(sign_urls)),
]
1 .ORM概念
Object Relational Mapping (对象关系映射) 其主要作用是:在编程中,把面向对象的概念跟数据库中表的概念对应起来。
…当然这只是从对象到SQL的映射,还有从SQL到对象的映射,也是类似的过程。 有了ORM,我们不需要再写繁琐的sql语句,一切以 python 语法为准,通过ORM提供的API,就可以操作数据库。
Django 框架可以通过 ORM 模型,来创建数据库表。具体步骤如下:
配置数据库信息( 项目目录/settings.py )
定义模型( 各应用目录/models.py )
生成迁移文件(pythonmanage.py makemigrations)
应用数据库迁移(pythonmanage.py migrate)
mysql 数据库配置为:
# 项目目录/settings.py DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',#数据库引擎
'NAME': 'course_autotp', #数据库名称
'USER': 'root', #用户名
'PASSWORD': '11111', #密码
'HOST': '127.0.0.1', #数据库IP
'PORT': '3306',#数据库端口
} }
#用户名 #密码 #数据库IP #数据库端口
在ORM中,一张表就是一个模型类,因此我们可以在 应用名/models.py 文件 中,先定义一个类,必须继承django自带的模型基类(models.Model)
2.对数据库进行操作
数据库操作主要包括数据的:新增、删除、修改、查询。 我们可以使用 Django 自带命令行工具,进行模型类数据库操作:
python manage.py shell
首先,在需要执行数据库操作的 py文件 中,从相关应用的 models 模块引入 模型,如从 sign.models 模块中引入 Event 模型
from sign.models import Event
def xxx():
# 这里写数据库操作代码
3.模型管理器
我们把: xxx模型类 . objects 称之为xxx模型的 模型管理器 。
3.1数据库操作
#新增
Event.objects.create(name='性能发布会',address='南京市花神大道23 号',limits=150)
event_dict = {'name':'测开发布会','address':'南京市鼓楼 区','limits':150}
Event.objects.create(**event_dict) # 解包
#查询
#例如1:查询 Event 表中的所有数据,返回 QuerySet 对象列表,代码如下:
eventList = Event.objects.all()
#例如2:条件过滤查询 Event 表中的数据,返回 QuerySet 对象列表,代码如 下:
eventList = Event.objects.filter(**kw) # 不加参数等同于all()
例如3:查询 Event 表中唯一数据(没有匹配结果或者匹配结果超过1条都会 报错),代码如下:
event = Event.objects.get(id=1) # 返回对象
#删除, limits 为100的数据
Event.objects.filter(limits=100).delete()
#修改
Event.objects.filter(limits=150).update(address='上海市')
#模糊查询
xx模型类.objects.filter(xxx字段名__xx关键字=xx值)
例如:
Event.objects.filter(limits__gte=100) # 人数大于等于100 Event.objects.filter(name__contains='双') # name 包含“双”字 Event.objects.filter(name__isnull=False) # name 不为空
4.数据库表关联
在关系型数据库中,表与表之间的关联关系,主要有三种:一对一,一对多,多对多 。
一对一:在任意一方,一般定义在次要的一方,用 models.OneToOneField 来定义。记住不能双方都定义
一对多:只能定义在多的一方,用models.ForeignKey 来定义
多对多:在任意一方,一般定义在后出现的,用 models.ManyToManyField 来定义。
【注意】定义在哪一方,哪一方就是字表
在模型中,设置好关联关系后, 为: 一对一、一对多的情况一样,在 中,会添加一个名称为【字段名_id】
的字段。如guest表中的event_id。 多对多不一样,在两个关联的模型表中,均不会添加字段,而是会出现一张中间
表,表名为:
【应用名 _ 模型1 _ 模型2】 如: sgin_guest_events ,其中模型1为定义的模型
5.on_delete外键策略
on_delete 外键策略,是解决当主表的数据删除时,从表的数据该如何处理的问 题。
外键删除策略有:
6.正向查询和反向查询
正向:子查父 子对象.父类名小写,就会返回一个父对象
反向:父查子 父对象.子类类名小写_set,就会返回一个【模块管理器】,也可以用别名(关联字段中related_name=别名),父对象.别名
#视图-》路由-》页面
class Department(models.Model):
title = models.CharField(verbose_name='部门',max_length=32)
class UserInfo(models.Model):
depart=models.ForeignKey(verbose_name='部
门',to='Department',related_name="u") #别名related_name ,正向查询没有影响,反向查询可以通过别名
departObj = Department.objects.get(id=9) departObj.userinfo_set.all()
user = models.CharField(verbose_name='用户称',max_length=32)
pwd= models.CharField(verbose_name='密码', max_length=256)
例如:部门表( Depart )和用户表( UserInfo )是一对多的关系,我们应该在多的一方(用户表),建立 Foreignkey 外键。这样, 多的一方通常也叫做 。根据子表(从表),来查找父表(主表)信息,我 们叫做 正向查询,和正向查询相反,通过父表(主表)来查询子表(从表),叫做 可以用.子表类名小写_set来查询
# 正向查询---用点就行
userObj = UserInfo.objects.get(id=1)
userObj.depart
# 反向查询---模型对象名小写_set
departObj = Department.objects.get(id=9)
depart_object.u.all()
# 报错,设置了 related_name别名后,原本的反向查询失效
departObj.userinfo_set.all()# 报错
CSRF跨站请求伪造,是一种常见的网络攻击手 段。 默认为我们开启了防范 攻击的机制,对于GET请求,一般来说没有这 个问题,通常是针对POST或PUT方法的。如果不做任何设置,在发送post请求时,会出
现 CSRF 验证失败,请求被中止
解决方法有以下三种(任选一种):
python manage.py test # 运行整个项目的测试用例
python manage.py test sign # 运行某个应用的测试用例
python manage.py test sign.tests # 运行某个模块的测试用例
python manage.py test sign.tests.xxxxClass
python manage.py test sign.tests.xxxxClass.xxxdef
例如:
# 3.签到保存
guest_obj.is_sign = True
guest_obj.save()
# 4.实际到场人数+1
event_obj.limits=event_obj.limits+1
event_obj.save()
以上代码片段共涉及到两次存数据库的操作,这两次存数据库的操作应该是一个原 子操作。即要么两次存数据库都成功,要么两次存数据库操作都失败。如果第一次修改 guest表成功,而第二次修改event表失败,这样就会导致发布会实际到场人数统计不一 致的bug。
【注意】在数据库中这种要成功就一起成功,要失败就一起失败的做法叫 ,如果这里签到成功但是后面的步骤失败了,那么数据库会发起回滚操作,将签到撤销。
在django中,可以用 with transaction.atomic(): 语句块实现事务操作。
with transaction.atomic():
# 4.签到=数据库更新
guest_obj.is_sign = True
guest_obj.save()
# 其他代码
# my_god = 10 / 0
# 5.修改发布会的已签到人数+1
event_obj.limits += 1
event_obj.save()