1、 新建虚拟环境

在该文件夹(learn)内,新建一个虚拟环境,learn\python-mvenvll_env

2、 激活虚拟环境

进入虚拟环境文件夹ll_env中的Scripts文件夹,利用命令行,激活虚拟环境ll_env\Scripts\activate

3、 安装Django

(如有,则忽略。建议在pycharm-settings里面projectinterpreter选择到一个有装满完整相关package的项目)

安装django.在learn文件夹内。learn\pipinstallDjango

4、 新建项目

在learn文件夹内新建一个项目(learning_log),\learn>django-adminstartprojectlearning_log

4.1、 项目(如project03)目录层级说明

Manage.py

一个命令行工具,可以使我们用多种方式对django项目进行交互。不修改,只用于使用。

project目录:

__init__.py

一个空文件,它告诉python这个目录应该被看作一个python包

Settings.py

项目的配置文件

Urls.py

项目的url声明

Wsgi.py

项目与wsgi兼容的web服务器入口

5、 启动服务器,测试是否建立成功

启动服务器,查看项目:pythonmanage.pyrunserver8080(将端口号改为8080,默认为8000)

6、 创建应用

创建应用:\项目文件夹>pythonmanage.pystartapp

6.1、 应用(如app0301)目录说明

admin.py进行站点配置

models.py创建模型

views.py创建视图

7、 激活应用(在settings.py)

在setting.py下加入,

INSTALLED_APPS=(

--snip--

'django.contrib.staticfiles',

#我的应用程序

'应用名称',)

8、 创建模型(在settings.py)

定义模型:

9、 配置数据库(在settings.py)

Django默认使用SQLite数据库,在settings.py文件中通过DATABASES选项进行数据库配置

9.1、 配置MySQL

Python3.x中安装的是PyMySQL,(在项目的文件夹下)__init__.py文件中写入两行代码

import pymysql
pymysql.install_as_MySQLdb()

以数据库hxiaoli-03为例进行示范:对settings.py中的DATABASES进行设置

DATABASES={
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME':'hxiaoli03',
'USER':'root',
'PASSWORD':'python098',
'HOST':'localhost',#数据库服务器IP地址
'PORT':'3306',
}
}

10、 在mysql中创建刚配置的数据库

例如,hxiaoli03

use mysql

create database hxiaoli03 ;

11、 定义语言和时间(在settings.py)

from django.utils.translation import gettext_lazy as _ # 要引入这个包
LANGUAGES = [
('zh-Hans', _('Chinese')),
]
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False # 设置为false,不然如果有需要体现修改时间的,时间就不是当前的北京时间

12、 创建超级用户

创建超级用户:\learn\learning_log>python manage.py createsuperuser

13、 定义模型

定义模型概述:models.py下定义模型(有一个数据表,就对应有一个模型),模型就是一个类,类的属性,就是数据表的一个字段。

from django.db import models # 模型类要继承models.Model类,Model是django 中定义了模型基本功能的类

# Create your models here.
class Grades(models.Model):
     g_name = models.CharField(max_length=20,verbose_name='班级名称')
     # verbose_name会使得页面阅览出来的表格列名为自己想要的g名称,如果没有定义,则为g_name
    
g_date = models.DateTimeField(verbose_name='成立日期')
     girl_num = models.IntegerField(verbose_name='女生人数')
     boy_num = models.IntegerField(verbose_name='男生人数')
     isDelete = models.BooleanField(default=False,verbose_name='是否被删除')

     class Meta:
         db_table = 'grades' # 将原来数据库中的app0301_grades 表名改成 grades
        
ordering = ['id']   # 按id 升序
        
verbose_name_plural = '班级信息管理' # 将网页预览出来的表格名字自定义命名,不然就是Gradess(两个s)


class Students(models.Model):
     s_name = models.CharField(max_length=20,verbose_name='学生姓名')
     s_gender = models.BooleanField(default=True,verbose_name='学生性别')
     s_age = models.IntegerField(verbose_name='学生年龄')
     s_content = models.CharField(max_length=30,verbose_name='学生简介')
     isDelete = models.BooleanField(default=False,verbose_name='是否被删除')
     s_grade = models.ForeignKey('Grades',on_delete=models.CASCADE ,verbose_name='所属班级'
) #定义外键的时候需要加上 on_delete=;否则,模型迁移时会出现错误

    
class Meta:
         db_table = 'students' # 将原来数据库中的app0301_grades 表名改成 grades
        
ordering = ['id']   # 按id 升序
        
verbose_name_plural = '学生信息管理' # 将网页预览出来的表格名字自定义命名,不然就是Gradess(两个s)

说明:不需要定义主键,在生成时自动添加,并且值为自动增加

13.1、关于isDelete

使用了这个标记,就等于增加了回收站功能,所以数据的删除,就不是直接删除,而是放入回收站。所谓放入回收站,就是将artilce的这个默认为0的标记改成1:

article.IsDelete=1;
article.update();

只有真正的彻底删除才需要 article.delete()

总之,这个问题是一个设计问题,不是技术问题;我只能告诉我是怎么设计的,至于你是否应该这么设计,完全看你自己的自由,技术上不是强制或者必须的(比如你用99或者-1来表示删除;比如你把数据放到一个临时表中……)。你自己多测试,看看运行的结果,应该会明白的。

13.2、django admin下拉列表不显示值,显示为object的处理

要加上:

def __str__(self):
     return self.g_name

# 返回的形式 ,而且不能是__unicode__(self):

13.3、定义外键的时候需要加上 on_delete=;

定义外键的时候需要加上 on_delete=;否则,模型迁移时会出现错误

TypeError: init() missing 1 required positional argument: ‘on_delete’

on_delete各个参数的含义如下:

由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)

14、 迁移模型

在manage.py所在文件夹内

\learn\learning_log>pythonmanage.pymakemigrations应用名称

\learn\learning_log>pythonmanage.pymigrate

15、 向管理网站中注册模型

from django.contrib import admin
from .models import Grades,Students
# Register your models here.
admin.site.register(Grades)
admin.site.register(Students)

16、 查询数据:

(l_env)F:\01-sunck\project>pythonmanage.pyshell

Python3.7.4(default,Aug92019,18:34:13)[MSCv.191564bit(AMD64)]onwin32

Type"help","copyright","credits"or"license"formoreinformation.

(InteractiveConsole)

>>>fromapp1.modelsimportGrades

>>>fromdjango.utilsimporttimezone

>>>fromdatetimeimport*

>>>Grades.objects.all()

<QuerySet[]>

添加数据的本质:创建一个模型类的对象实例

17、 在数据库中生成数据表

17.1、生成迁移文件

执行pythonmanage.py makemigrations在migrations目录下生成一个迁移文件,此时数据库中还没有生成数据表

17.2、执行迁移

执行pythonmanage.py migrate相当于执行MySQL语句创建了数据表

18、 测试数据操作

进入到pythonshell,执行python manage.py shell

18.1、查询所有数据

类名.objects.all()

示例:Grades.objects.all()

引入包,并查询所有数据

In [1]: from app0301.models import Grades,Students

In [2]: from django.utils import timezone

In [3]: from datetime import *

In [4]: Grades.objects.all()

Out[4]: <QuerySet []> # 未添加数据时为空

18.2、添加数据

本质:创建一个模型类的对象实例

示例:CMD窗口下:

grade1=Grades()

grade1.gname="python04"

grade1.gdate=datetime(year=2017,month=7,day=17)

grade1.ggirlnum=3

grade1.gboynum=70

grade1.save()

18.3、查看某个对象

类名.objects(pk=索引号)

示例:

Grades.objects.get(pk=2)

Grades.objects.all()

18.4、修改某个数据

模型对象属性=新值

示例:

grade2.gboynum=60

grade2.save()

18.5、删除数据

模型对象.delete()

grade2.delete()

注意:这是物理删除,数据库中的相应数据被永久删除

18.6、关联对象

示例:

stu=Students()

stu.sname="XueYanmei"

stu.sgender=False

stu.sage=20

stu.scontend="IamXueYanmei"

stu.sgrade=grade1

stu.save()

需求:猎取python04班级的所有学生

对象名.关联的类名小写_set.all()

示例:grade1.students_set.all()

需求:创建曾志伟,属于python04班级

示例:

stu3=grade1.students_set.create(sname=u'ZhenZhiwei',sgender=True,scontend=u"IamZhenZhiwei",sage=45)

注意:这样创建的数据直接被添加到了数据库当中。

启动服务器:

格式:pythonmanage.pyrunserverip:port

注意:ip可以不写,不写代表本机ip

端口号默认是8000

pythonmanage.pyrunserver

说明:

这是一个纯python编写的轻量级web服务器,仅仅在开发测试中使用这个

19、 Admin站点管理:

概述:内容发布:负责添加,修改,删除内容的公告访问

19.1、自定义管理页面:

19.1.1、 属性说明

19.1.1.1、 列表页属性与添加,修改页属性

#列表页属性

list_display=[]#显示字段设置

list_filter=[]#过滤字段设置

search_fields=[]#搜索字段设置

list_per_page=[]#分页设置

#添加,修改页属性

fields=[]#规定属性的先后顺序

fieldsets=[]#给属性分组注意:fields与fieldsets不能同时使用

属性示例:

from django.contrib import admin
from .models import Grades, Students
# Register your models here.
class GradesAdmin(admin.ModelAdmin):

# 该列表页管理类一定要写在admin.site.register(Grades,GradesAdmin),不然会提示“GradesAdmin”还未被定义。先定义后使用。Admin.py里面都要遵循先创建类再使用的原则,不然会提示不存在。
# 列表页属性
list_display = ['pk', 'g_name', 'g_date', 'girl_num', 'boy_num', 'isDelete']
list_filter = ['g_name']
search_fields = ['g_name']
list_per_page = 5
# 添加,修改页属性
fields = ['g_date', 'girl_num', 'boy_num', 'isDelete']
admin.site.register(Grades,GradesAdmin)

----- StudentAdmin就不列出了-----

19.1.1.2、 列表页属性效果图:

19.1.1.3、 Fields效果图:

19.1.1.4、 Fieldsets效果图

19.1.2、 关联对象:(在创建一个班级时可以直接添加几个学生)

需求:在创建一个班级时可以直接添加几个学生

class StudentsInfo(admin.TabularInline):#可选参数admin.StackedInline
    
model = Students
     extra = 2

class GradesAdmin(admin.ModelAdmin):
     inlines = [StudentsInfo]
19.1.3、 布尔值显示问题示例:

class StudentsAdmin(admin.ModelAdmin):
def gender(self):
if self.s_gender:
return '男'
else:
return '女'
# 设置页面列的名称
gender.short_description = "性别"
def is_delete(self):
if self.isDelete:
return '已被删除'
else:
return '未被删除'
list_display = ['pk', 's_name', gender, 's_content', 's_grade',is_delete] # 将上面定义的方法的方法名传进来
list_filter = ['s_grade']
search_fields = ['s_name']
list_per_page = 3
# 添加,修改页属性
fields = ['s_name', 's_gender', 's_content', 's_grade','isDelete']

**:要先定义方法再进行传值

19.1.4、 执行动作按钮位置:

class StudentsAdmin(admin.ModelAdmin):

…snip…
actions_on_top = False
actions_on_bottom = True
admin.site.register(Grades,GradesAdmin)

19.2、使用装饰器完成注册:

@admin.register(Students)

classStudentsAdmin(admin.ModelAdmin):

defgender(self):

...snip...

actions_on_top=False

actions_on_bottom=True

视图的基本使用

概述:

在Django中,视图是对web请求进行回应

视图就是一个python函数,在views.py文件中定义。

定义视图:

示例:在myApp\views.py中写入

fromdjango.shortcutsimportrender

#Createyourviewshere.

fromdjango.httpimportHttpResponse

defindex(request):

returnHttpResponse("Sunckisagoodman")

配置url:方法一:path方法:

修改project目录下的urls.py文件:

fromdjango.contribimportadmin

fromdjango.urlsimportpath,include

urlpatterns=[

path('admin/',admin.site.urls),

path('',include('myApp.urls')),

]

在myApp应用目录下创建urls.py文件:

fromdjango.urlsimportpath,include

from.importviews

urlpatterns=[

path('',views.index),

]

配置url:方法二:url方法:

修改project目录下的urls.py文件:

fromdjango.contribimportadmin

fromdjango.conf.urlsimporturl,include

urlpatterns=[

url(r'^admin/',admin.site.urls),

url(r'^',include('myApp.urls')),

]

在myApp应用目录下创建urls.py文件:

fromdjango.conf.urlsimporturl

from.importviews

urlpatterns=[

url(r'^$',views.index),

]

模板的基本使用:

概述:模板是HTML页面,可以根据视图中传递过来的数据进行填充

创建模板:

创建templates目录,在目录下创建对应项目的模板目录(project/templates/myApp)

配置模板路径:

修改settings.py文件下的TEMPLATES下的'DIRS'为'DIRS':[os.path.join(BASE_DIR,'templates')],

定义grades.html与students.html模板:

在templates\myApp\目录下创建grades.html与students.html模板文件

模板语法:

{{输出值,可以是变量,也可以是对象,属性}}

{%执行代码段%}

http://127.0.0.1:8000/grades

写grades.html模板:

<!doctypehtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"

content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title>班级信息</title>

</head>

<body>

<h1>班级信息列表</h1>

<ul>

<!--[python04,python05,python06]-->

{%forgradeingrades%}

<li>

<ahref="#">{{grade.gname}}</a>

</li>

{%endfor%}

</ul>

</body>

</html>

定义视图:myApp\views.py

from.modelsimportGrades

defgrades(request):

#去模板里取数据

gradesList=Grades.objects.all()

#将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器

returnrender(request,'myApp/grades.html',{"grades":gradesList})

配置url:myApp\urls.py

urlpatterns=[

url(r'^$',views.index),

url(r'^(\d+)/(\d+)$',views.detail),

url(r'^grades/',views.grades)

]

http://127.0.0.1:8000/students

写students.html模板

<!doctypehtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"

content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title>学生页面</title>

</head>

<body>

<h1>学生信息列表</h1>

<ul>

{%forstudentinstudents%}

<li>

{{student.sname}}--{{student.scontend}}

</li>

{%endfor%}

</ul>

</body>

</html>

定义视图:myApp\views.py

from.modelsimportStudents

defstudents(request):

studentsList=Students.objects.all()

returnrender(request,'myApp/students.html',{"students":studentsList})

配置url:myApp\urls.py

urlpatterns=[

url(r'^$',views.index),

url(r'^(\d+)/(\d+)$',views.detail),

url(r'^grades/',views.grades),

url(r'^students/',views.students),

]

需求:点击班级,显示对应班级的学生名字

运行不正常https://www.bilibili.com/video/av17879644/?p=12

Django流程梳理

创建工程:执行django-adminstartproject工程名

创建项目:执行pythonmanage.pystartapp项目名称

激活项目:修改settings.py中的INSTALLED_APPS

配置数据库:

修改__init__.py文件

修改settings.py文件中的DATABASES

创建模型类:在项目目录下的models.py文件中创建

生成迁移文件:执行pythonmanage.pymakemigrations

执行迁移:执行pythonmanage.pymigrate

配置站点:略

创建模板目录/项目模板目录

在settings.py中的TEMPLATES添加templates路径

在工程目录下(project)修改urls.py

在项目目录下创建urls.py

使用他人Django代码需要的简易修改:

1.在settings.py中修改数据库名

2.在settings.py中修改数据库密码

3.删除由内向外文件(在对应目录里鼠标右键删除)

4.在数据库中创建对应第一步的数据库(自己在SQL中创建)

5.执行生成迁移文件

6.执行迁移

7.启动服务

8.浏览器测试

Django模型

Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API

我们可以根据不同的业务需求选择不同的数据库。

配置数据库

修改工程目录下的__init__.py文件

importpymysql

pymysql.install_ad_MySQLdb()

修改settings.py文件中的DATABASES

开发流程

配置数据库

定义模型类:一个模型都在数据库中对应一张数据库表

生成迁移文件

执行迁移生成数据表

使用模型类进行增删改查

ORM

概述:对象-关系-映射

任务:

根据对象的类型生成表结构

将对象,列表的操作转换成SQL语句

将SQL语句查询到的结果转换为对象,列表

优点:

极大的减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码的问题

定义模型

创建模型类

元选项

在模型类中定义Meta类,用于设置元信息

示例:

classMeta:

db_table="students"

ordering=['id']

db_table

定义数据表名,推荐用小写字母,数据表名默认为项目名小写_类名小写

ordering

对象的默认排序字段,获取对象的列表时使用

示例:

ordering['id']id按升序排列

ordering['-id']id按降序排列

注意:排序会增加数据库开销

模型成员

类属性

隐藏类属性objects:也是模型类的一个管理器

是Manager类型的一个对象,作用是与数据库进行交互。用mysqlworkbench或者mysql命令行窗口修改,最后一次修改时间没有体现。但是如果用pycharmshell修改就会体现。如果想要体现当前的系统时间的话,必须在settings里面设置,TIME_ZONE='Asia/Shanghai'USE_TZ=False

当定义模型类时没有指定管理器,则Django为模型创建一个名为objects的管理器

自定义管理器示例:

定义stuObj管理器:(作用不大)

stuObj=models.Manager()#在Students类里面,是大写的Manage,不是小写的manage

当为模型指定模型管理器,Django就不再为模型类生成objects模型管理器了。即,Students.objects.get(pk=1)就会出错。

自定义管理器Manager类

模型管理器是Django的模型进行与数据库交互的窗口,一个模型可以有多个模型管理器

作用:

1. 向管理器类中添加额外的方法

2. 修改管理器返回的原始查询集。(什么是查询集:比如Student.objects.all(),但是原始查询集是把数据库里面所有的信息都返回回来,而修改原始查询集就可以进行一定的过滤。)通常会重写get_queryset()方法

代码示例:

classStudentsManager(models.Manager):

defget_queryset(self):

returnsuper(StudentsManger,self).get_queryset().filter(isDelete=False)

classStudents(model.Moder):

#自定义模型管理器

#当自定义模型管理器,objects就不存在了

stuObj=models.Manger()

stuObj2=StudentsManager()

创建对象

目的:向数据库中添加数据

当创建对象时,django不会对数据库进行读写操作,当调用save()方法时才与数据库交互,将对象保存在数据库表中。

注意:__init__方法已经在父类models.Model中使用,在自定义的模型中无法使用。

方法:

在模型类中增加一个类方法,示例如下:

#定义一个类方法创建对象

@classmethod#表示类方法

defcreateStudents(cls,name,age,gender,content,grade,lasttime,isdelete=False):#cls代表前面的ClassStudents,假如前面没有假如@classmethod,则括号里面写cls

stu=cls(sname=name,sage=age,sgender=gender,scontend=content,sgrade=grade,lastTime=lasttime,isDelete=isdelete)#传值

returnstu

在自定义管理器中添加一个方法,示例如下:

classStudentsManager(models.Manager):

defget_queryset(self):

returnsuper(StudentsManager,self).get_queryset().filter(isDelete=False)

defcreateStudent(self,name,age,gender,contend,grade,lastT,createT,isD=False):

stu=self.model()

#print(type(grade))

stu.sname=name

stu.sage=age

stu.sgender=gender

stu.scontend=contend

stu.sgrade=grade

stu.lastTime=lastT

stu.createTime=createT

returnstu

模型查询

概述

查询集表示从数据库获取的对象的集合

查询集可以有多个过滤器

过滤器就是一个函数,基于所给的参数限制查询集结果

从SQL角度来说,查询集和select语句等价,过滤器就像where条件

查询集

在管理器上调用过滤器方法返回查询集

查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用

惰性执行

创建查询集不会带来任何数据库的访问,直到调用数据库时,才会访问数据

直接访问数据的情况:

迭代

序列化

与if合用

返回查询集的方法称为过滤器

all():返回查询集中的所有数据

filter():保留符合条件的数据

filter(键=值)

filter(键=值,键=值)

filter(键=值).filter(键=值)且的关系

exclude():过滤掉符合条件的

order_by():排序

values():一条数据就是一个字典,返回一个列表

get()

返回一个满足条件的对象

注意:

如果没有找到符合条件的对象,会引发模型类.DoesNotExist异常

如果找到多个对象,会引发模型类MultipleObjectsReturned异常

count():返回查询集中对象的个数

first():返回查询集中第一个对象

last():返回查询集中最后一个对象

exits():判断查询集中是否有数据,如果有数据返回True,否则返回False.

限制查询集

查询集返回列表,可以使用下标的方法进行限制,等同于sql中的limit语句

注意:下标不能是负数

示例:studentsList=Students.stuObj2.all()[0:5]

查询集的缓存

概述:

每个查询集都包含一个缓存,来最小化对数据库的访问

在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,Django会将查询出来的数据做一个缓存,并返回查询结果。

以后的查询直接使用查询集的缓存

字段查询

概述

实现了sql中的where语句,作为方法filter(),exclude(),get()的参数

语法:属性名称__比较运算符=值

外键:属性名称_id

转义:类似sql中的like语句

like有关情况看我哥他%是为了匹配点位,匹配数据中的%使用(wherelike"\%")

filter(sname__contains="%")

比较运算符

exact:判断,大小写敏感

filter(isDelete=False)

contains:是否包含,大小写敏感

studentsList=Students.stuObj2.filter(sname__contains="孙")

startswith,endswith:以value开头或结尾,大小写敏感

以上四个在前面加上i,就表示不区分大小写iexact,icontains,istartswith,iendswith

isnull,isnotnull

是否为空

filter(sname__isnull=False)

in:是否包含在范围内

gt大于,gte大于等于,lt小于,lte小于等于

year,month,day,week_day,hour,minute,second

studentsList=Students.stuObj2.filter(lastTime__year=2017)

跨关联查询

处理join查询

语法:

模型类名__属性名__比较运算符

#描述中带有‘薛延美’这三个字的数据是属于哪个班级的

grade=Grades.objects.filter(students__scontend__contains='薛延美')

print(grade)

查询快捷pk代表的主键

聚合函数

使用aggregate函数返回聚合函数的值

Avg

Count

Max

maxAge=Student.stuObj2.aggregate(Max('sage'))

maxAge为最大的sage。

Min

Sum

F对象

可以使用模型的A属性与B属性进行比较

fromdjango.db.modelsimportF,Q

defgrades1(request):

g=Grades.objects.filter(ggirlnum__gt=F('gboynum'))

print(g)

#[<Grades:python02>,<Grades:python03>]

returnHttpResponse("OOOOOOOo")

支持F对象的算术运算

g=Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)

Q对象

概述:过滤器的方法的关键字参数,条件为And模式

需求:进行or查询

解决:使用Q对象

defstudents4(request):

studentsList=Students.stuObj2.filter(Q(pk__lte=3)|Q(sage__gt=50))

returnrender(request,'myApp/students.html',{"students":studentsList})

只有一个Q对象的时候,就是用于正常匹配条件

studentsList=Students.stuObj2.filter(~Q(pk__lte=3))

~Q是取反

定义属性

概述:

django根据属性的类型确定以下信息

当前选择的数据库支持字段的类型

渲染管理表单时使用的默认html控件

在管理站点最低限度的验证

django会为表增加自动增长的主键列,每个模型只能有一个主键列,如

果使用选项设置某属性为主键列后,则django不会再生成默认的主键列

属性命名限制

遵循标识符规则,且变量不能与Python保留字相同

由于django的查询方式,不允许使用连续的下划线

定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,

为了方便使用,被导入到django.db.models中

使用方式

导入:fromdjango.dbimportmodels

通过models.Field创建字段类型的对象,赋值给属性

逻辑删除

对于重要类型都做逻辑删除,不做物理删除,实现方法是定义idDelete属性,

类型为BooleanField,默认值为False

字段类型

autoField

一个根据实际ID自动增长的IntegerField,通常不指定,

如果不指定,一个主键字段将自动添加到模型中

CharField(max_length=字符长度)

字符串,默认的表彰样式是TextInput

TextField

大文本字段,一般超过4000时使用,默认的表单控件是Textarea

IntegerField

整数

DecimalField(max_digits=None,decimal_places=None)

使用Python的Decimal实例表示的十进制浮点数

参数说明

DecimalField.max_digits

位数总数

DecimalField.decimal_places

小数点后的数字位置

FloatField

使用Python的float实例来表示的浮点数

BooleanField

True/False字段,此字段的默认表彰控制是CheckboxInput

NullBooleanField

支持Null,True,False三种值

DateField([auto_now=False,auto_now_add=False])

使用Python的datetime.date实例表示的日期

参数说明:

DateField.auto_now

每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”

的时间戳,它总是使用当前日期,默认为False

DateField.auto_now_add

当前对象第一次被创建时自动设置当前时间,用于创建的时间戳,

它总是使用当前日期,默认为False

说明

该字段默认对应的表单控件是一个TextInput.在管理员站点添加了一个

JavaScript写的日历控件,和一个“Today”的快捷按钮,包含了一个额外

的invalid_date错误消息键

注意

auto_now_add,auto_now,anddefault这些设置是相互排斥的,他们之间

的任何组合将会发生错误的结果

TimeField

使用Python的datetime.time实例表示的时间,参数同DateField

DateTimeField

使用Python的datetime

datetime实例表示的日期和时间,参数同DateField

FileField

一个上传文件的字段

ImageField

继承了FileField的所有属性和方法,但对上传的对象进行校验,

确保它是一个有效的image

字段选项

概述

通过字段选项,可以实现对字段的约束

在字段对象中通过关键字参数指定

null

如果为True,Django将空值以NULL存储在数据库中,默认值为False

blanke

如果为True,则该字段允许为空白,默认值为False

注意

null是数据库范畴的概念,blank是表彰验证范畴的概念

db_column

字段的名称,如果未指定,则使用属性的名称

db_index

若值为True,则在表中会为此字段创建索引

default

默认值

primary_key

若为True,则该字段会成为模型的主键字段

unique

如果为True,这个字段在表中必须有唯一值

关系

分类

ForeignKey:一对多,将字段定义在多的端中

ManyToManyField:多对多,将字段定义在两端中

OneToOneField:一对一,将字段定义在任意一端中

用一访问多

格式

对象.模型类小写_set

示例

grade.students_set

用一访问一

格式

对象.模型类小写

示例

grade.studnets

访问id

格式

对象.属性_id

示例

student.sgrade_id

视图

概述:

作用:视图接收web请求,并响应web请求

本质:视图就是python中的一个函数

响应:

响应过程:

用户在浏览器中输入网址www.sunck.wang/sunck/index.html

---网址--->

django获取网址信息,去掉IP与端口号,网址变成:sunck/index.html

---虚拟路径与文件名--->

url管理器逐个匹配urlconf,记录视图函数

---视图函数名--->

视图管理,找到对应的视图去执行,返回结果给浏览器

---响应的数据--->

返回第一步:用户在浏览器中输入网址

网页

重定向

错误视图

404视图:找不到网页(url匹配不成功时返回)时返回

在templates目录下定义404.html

<!doctypehtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"

content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title>Document</title>

</head>

<body>

<h1>页面丢失</h1>

<h2>{{request_path}}</h2>

</body>

</html>

request_path:导致错误的网址

配置settings.py

DEBUG

如果为True,永远不会调用404页面,需要调整为False才会显示

ALLOWED_HOSTS=['*']

500视图:在视图代码中出现错误(服务器代码错误)

400视图:错误出现在客户的操作

JSON数据

url配置

配置流程:

制定根级url配置文件

settings.py文件中的ROOT_URLCONF

ROOT_URLCONF='project.urls'

默认实现了

urlpatterns

一个url实例的列表

url对象

正则表达式

视图名称

名称

url匹配正则的注意事项

如果想要从url中获取一个值,需要对正则加小括号

匹配正则前方不需要加'/'

正则前需要加'r'表示字符串不转义

引入其他url配置

在应用中创建urls.py文件,定义本应用的url配置,在工程urls.py中使用include方法

project\urls.py

fromdjango.contribimportadmin

fromdjango.conf.urlsimporturl,include

urlpatterns=[

url(r'^admin/',admin.site.urls),

url(r'^',include('myApp.urls',namespace="myAPP")),

]

myApp\urls.py

fromdjango.urlsimportpath,include

fromdjango.conf.urlsimporturl

from.importviews

urlpatterns=[

url(r'^$',views.index,name="index"),

]

url的反向解析

概述:如果在视图,模板中使用了硬编码链接,在url配置发生改变时,动态生成链接的地址

解决:在使用链接时,通过url配置的名称,动态生成url地址

作用:使用url模板

视图函数

定义视图:

本质:一个函数

视图参数:

一个HttpRequest的实例

通过正则表达式获取的参数

位置:一般在views.py文件下定义

HttpRequest对象

概述:

服务器接收http请求后,会根据报文创建HttpRequest对象

视图的第一个参数就是HttpRequest对象

django创建的,之后调用视图时传递给视图

属性

path:请求的完整路径(不包括域名和端口)

method:表示请求的方式,常用的有GET,POST

encoding:表示浏览器提交的数据的编码方式,一般为utf-8

GET:类似于字典的对象,包含了get请求的所有参数

POST:类似于字典的对象,包含了post请求的所有参数

FILES:类似字典的对象,包含了所有上传的文件

COOKIES:字典,包含所有的cookie

session:类似字典的对象,表示当前会话

方法

is_ajax():如果是通过XMLHttpRequest发起的,返回True

QueryDict对象

request对象中的GET,POST都属于QueryDict对象

方法:

get():

根据键获取值,只能获取一个值

www.sunck.wang/abc?a=1&b=2&c=3

getlist()

将键的值以列表的形式返回

可以获取多个值

www.sunck.wang/abc?a=1&b=2&c=3

GET属性

获取浏览器传递过来数据

www.sunck.wang/abc?a=1&b=2&c=3

urls.py

url(r'^get1',views.get1),#结尾不能加$,否则无法匹配

views.py

defget1(request):

a=request.GET.get('a')

b=request.GET.get('b')

c=request.GET.get('c')

returnHttpResponse(a+""+b+""+c)

www.sunck.wang/abc?a=1&a=2&c=3

urls.py

url(r'^get2',views.get2),

views.py

defget2(request):

a=request.GET.getlist('a')

a1=a[0]

a2=a[1]

c=request.GET.get('c')

returnHttpResponse(a1+""+a2+""+c)

POST属性

使用表单模拟POST请求

关闭CSRF:project\project\settings.py

MIDDLEWARE=[

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.middleware.common.CommonMiddleware',

#'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

示例:

defshowregist(request):

returnrender(request,'myApp/regist.html',)

defregist(request):

name=request.POST.get("name")

gender=request.POST.get("gender")

age=request.POST.get("age")

hobby=request.POST.getlist("hobby")

print(name)

print(gender)

print(age)

print(hobby)

returnHttpResponse("regist")

路径:

url(r'^showregist/$',views.showregist),

url(r'^showregist/regist/$',views.regist),

页面:

<!doctypehtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"

content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title>注册</title>

</head>

<body>

<formaction="regist/"method="post">

姓名:<inputtype="text"name="name"value=""/>

<hr>

性别:<inputtype="radio"name="gender"value="1">男<inputtype="radio"name="gender"value="0">女

<hr>

爱好:<inputtype="checkbox"name="hobby"value="power"/>权利<inputtype="checkbox"name="hobby"value="money">金钱<inputtype="checkbox"name="hobby"value="beauty">美女<inputtype="checkbox"name="hobby"value="Tesla">Tesla

<hr>

<inputtype="submit"value="注册">

</form>

</body>

</html>

HttpResponse对象

概述:

作用:给浏览器返回数据

HttpRequest对象是由Django创建的,HttpResponse对象是由程序员创建

用法:

不用模板,直接返回数据

语句示例:returnHttpResponse("Sunckisagoodman")

调用模板

使用render方法

原型:render(request,templateName[,context])

作用:结合数据和模板,返回一个完整的HTML页面

参数:

request:请求体对象

templateName:模板路径

context:传递给需要渲染在模板上的数据

属性

content:表示返回内容

charset:编码格式

status_code:响应状态码

200

304

404

400

content-type:指定输出的MIME类型

方法

init:使用页面内容实例化HttpResponse对象

write(content):以文件的形式写入

flush():以文件的形式输出缓冲区

set_cookie(key,value,maxAge=None,exprise=None)

delete_cookie(key):

删除cookie

如果删除一个不存在的cookie,就当什么都没发生

子类HttpResponseRedirect

功能:重定向,服务器端的跳转

简写

redirect(to)

to推荐使用反向解析

示例:

fromdjango.httpimportHttpResponseRedirect

fromdjango.shortcutsimportredirect

defredirect1(request):

#returnHttpResponseRedirect('/redirect2')

returnredirect('/redirect2')

defredirect2(request):

returnHttpResponse("我是重定向后的视图")

子类JsonResponse

返回Json数据,一般用于异步请求

__init__(self.data)

data字典

注意:Content-type类型为application/json

状态保持

http协议是无状态的,每次请求都是一次新的请求,它不记得之前的请求。

客户端与服务器的一次通信就是一次会话

实现状态的保持,在客户端或服务端存储有关会话的数据

存储的方式

cookie:所有数据存储在客户端,不要存储敏感的数据

session:所有的数据存储在服务端,在客户端用cookie存储session_id

状态保持的目的:

在一段时间内跟踪请求者的状态,可以实现跨页面访问当前的请求者的数据

注意:不同的请求者之间不会共享这个数据,与请求者一一对应

启用session:project\project\settings.py

INSTALLED_APPS'django.contrib.sessions',

MIDDLEWARE'django.contrib.sessions.middleware.SessionMiddleware',

使用session

启用session后,每个httpRequest对象都有一个session属性

get[key,default=None]根据键获取session值

clear()清空所有会话

flush()删除当前会话并删除会话的cookie

示例:

#session

defmain(request):

#取session

username=request.session.get('name','游客')

print(username)

returnrender(request,'myApp/main.html',{'username':username})

deflogin(request):

returnrender(request,'myApp/login.html')

defshowmain(request):

print("*****************")

username=request.POST.get('username')

#存储session

request.session['name']=username

returnredirect('/main/')

fromdjango.contrib.authimportlogout

defquit(request):

#清除session

logout(request)#方法1,推荐

#request.session.clear()#方法2

request.session.flush()#方法3

returnredirect('/main/')

设置session过期时间

set_expiry(value)

request.session.set_expiry(10)设置为10秒后过期

如果不设置,2个星期后过期

value设置为0代表关闭浏览器时过期

value设置为None代表设置永不过期,不推荐

02-14 02:09