目录
MVC设计模式
MTV设计模式
安装
基本操作
设计表结构
配置mysql
创建应用:
激活应用:
定义模型:
在数据库中生成数据表:
测试数据操作:
启动服务器:
Admin站点管理:
使用装饰器完成注册:
视图的基本使用
模板的基本使用:
需求:点击班级,显示对应班级的所有学生
模型:
关系:
创建模型类:
元选项:
模型成员:
模型查询:
优点:降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
本质上与MVC没有差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同
编程模式:Model(模型),Template(模板),View(视图)
Model:负责业务对象与数据库的对象(ORM):ORM对应对象--关系--映射
Template:负责如何把页面展示给用户;也就是一个HTML页面
View:负责业务逻辑,并在适当的时候调用model和Template
注意:Django还有一个url分发器,它的作用是将一个个URL的页面请求,分发给不同的view处理,view再调用相应的model和Template。
这就是一个Django的过程,用户输入网址,发送给服务器,Django里面的URL控制器就解析这个url然后确定相应要访问的页面,然后交给不同的视图处理,视图就去model中拿数据,model就去数据库中拿数据,model就把数据返回给视图,视图又把数据返回给模板,模板就把数据渲染,渲染之后就形成了一个HTML完整的页面,视图就将这个页面返回给浏览器。
pip install django
验证安装是否成功:进入python命令行:import django;;django.get_version();即可看到版本号
在你电脑里面创建一个合适的文件夹——>在cmd中cd进入那个文件夹——>使用
查看项目文件层级:
manage.py: 一个命令行工具,可以使我们用多种方式对Django项目进行交互
project目录下:_init_.py:一个空文件,它告诉python这个目录应该被看做一个python包
settings.py:项目的配置文件
urls.py:项目的URL生命
wsgi.py:项目与WSGI兼容的web服务器入口
配置数据库:注意:Django默认使用SQLite数据库,要在settings.py中,通过DATABASES选项进行数据库配置。
#在_init_.py文件中加入这两行
import pymysql
pymysql.install_as_MySQLdb()
在settings.py中修改DATABASES选项:ENGINE变为:
'ENGINE': 'django.db.backends.mysql',
大部分数据库格式都是这样
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "exampel",#数据库名
'USER': "root", #用户名
'PASSWORD': "123456", #数据库密码
'HOST': "localhost", #数据库服务器IP
'PORT': "3306", #端口
}
}
完整如上。
在一个项目中可以创建多个应用,每个应用进行一种业务处理
在cmd中进入刚刚创建的项目目录中执行
python manage.py startapp myapp1
#myapp1是你的应用名
目录说明:然后可以发现在项目文件夹下多了个myapp1文件夹,里面的admin.py表示站点,modles.py是为了写模型的,这个view.py是用来写视图的
在settings.py中里面配置INSTALLED_APPS。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp1',#加入这个即可,上面都是他自带的
]
概述:有一个数据表,就对应一个模型,在myapp1中的models.py中定义模型
模型类要继承models.Model类,模型类中的属性就对应我们数据库表中的字段
from django.db import models
# Create your models here.
#这是班级表
class Grades(models.Model):
gname = models.CharField(max_length=20)
gdate = models.DateTimeField()
ggirlnum = models.IntegerField()
gboynum = models.IntegerField()
isDelete = models.BooleanField(default=False)
#这是学生表
class Students(models.Model):
sname = models.CharField(max_length=20)#字段属于这个属性时必须定义max_length!
sgender = models.BooleanField(default=True)
sage = models.IntegerField()
scontend = models.CharField(max_length=20)
isDelete = models.BooleanField(default=False)
#所属班级的话,由于是一对多的关系,外键写在多的里面,即写在学生这里
sgrade = models.ForeignKey("Grades",on_delete=models.CASCADE)
#关联外键,关联Grades中的主键,且注意写外键的时候要加上on_delete=models.CASCADE这个关键词
说明:不需要定义主键,在生成时自动添加,并且值自动添加
生成迁移文件——>执行迁移
生成迁移文件:在项目所在文件夹的下面执行:
python manage.py makemigrations
成功的样子,其作用是在migrations下生成一个迁移文件,此时数据库中还没有表
Migrations for 'myapp1':
myapp1\migrations\0001_initial.py
- Create model Grades
- Create model Students
#有错误的根据提示改错
继续执行:
python manage.py migrate
#执行迁移,相当于执行sql语句创建数据表
说明:以后我们去操作数据就要通过模型的对象,因为模型的对象对应表里面的一个字段,我们创造一个对象就是表里面的一条数据了。
进入到python shell:python manage.py shell
引入一些包:
from myapp1.models import Grades,Students
from django.utils import timezone
from datetime import *
查询所有数据:
Grades.objects.all()
#类名.objects.all()
grade1 = Grades()
grade1.gname = "python04"
grade1.gdate = datetime(year=2019,month=3,day=15)
grade1.ggirlnum = 22
grade1.gboynum = 13
grade1.save()#这个对象调用save他就会存到数据库中
会输出:
]>
#这样就很烦,所以回到models在Grades类中加入
def __str__(self):
return "%s-%d-%d" %(self.gname, self.ggirlnum, self.gboynum)
#这样就是设置了调用该类的时候就会执行这个
Grades.objects.all()
#输出如下
]>
Grades.objects.get(id=2)
#类名.objects.get(id=2), id也就是主键,输出如下
g = Grades.objects.get(id=2)
grade2.ggirlnum = 20
#模型对象.属性 = 新值
grade2.save()#记得save才会同步到数据库中。
grade2.delete()
#模型对象.delete(),注意这是物理删除,数据库中的表里的数据直接被删除,不需要save同步
grade1 = Grades.objects.get(pk=1)
stu = Students()
stu.name = "张胜三"
stu.sgender = False
stu.sage = 20
stu.scontend = "我叫张胜三"
stu.sgrade = grade1
stu.save()
获得关联对象的集合:需求:获取python04班级的所有学生
grade1.students_set.all()
#students_set是自带的,一对多,多的列名都是小写的
#格式:类名.关联的类名小写_set.all()
需求:创建张即,属于python04班级
stu3 = grade1.students_set.create(sname=u'张即',sgender=True,scontend='我叫张即',sage=45)
#注意这里的汉字需要用u进行转码,且这里的create直接存入到了数据库,不用save
注意汉字转码!直接添加到数据库中!
#格式
python manage.py runserver ip:port
注意:这个ip可以不写,不写的话代表本机ip。端口号默认8000,可以修改。也就是可以直接python manage.py runserver
这是一个纯python写的轻量级web服务器,仅仅在开发测试中使用!
概述:主要负责内容发布和公告访问
内容发布:负责添加、修改、删除内容
在settings.py中的
INSTALLED_APPS添加'django.contrib.admin',默认是已添加的
python manage.py createsuperuser
依次输入用户名、邮箱、密码
汉化:修改settings.py中的LANGUAGE_CODE和TIME_ZONE
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
#保存刷新网页即可生效,延迟会有10s左右
from .models import Grades,Students
#注册
admin.site.register(Grades)
admin.site.register(Students)
把你需要改的那个类的类名加上admin就行了,然后继承默认界面:modeladmin
并且注册的时候用到就行了。
from .models import Grades,Students
#注册
class GradeAdmin(admin.ModelAdmin):
#列表页属性
#显示字段
list_display = ['pk', 'gname', 'gdate', 'ggirlnum', 'gboynum', 'isDelete']
#过滤字段
list_filter = ['gname']
#搜索字段
search_fields = ['gname']
#分页
list_per_page = 5
#添加、修改页属性
#可以规定属性的先后顺序,注意这里不能加pk,因为这里的pk我们弄的是自动生成的,而不是自己指定的
#fields = ['ggirlnum', 'gboynum', 'gname', 'gdate', 'isDelete']
#fields和fieldsets不能同时使用,fieldsets是给属性分组
fieldsets = [
("num", {"fields":['ggirlnum', 'hboynum']}),
("base", {"fields":['gname', 'gdate', 'isDelete']}),
]
admin.site.register(Grades, GradeAdmin)#自定义的页面,要放在注册的这里
admin.site.register(Students)
需求:在创建一个班级时可以直接添加几个学生
根据一对多的关系,在创建班级的时候,能直接添加几个学生
class StudentsInfo(admin.TabularInline):#这里也可以继承StackedInline
model = Students
extra = 2
class GradeAdmin(admin.ModelAdmin):#上面加的类名随意,只要在下面的inlines里面加入即可
inlines = [StudentsInfo]
def gender(self):
if self.sgender:
return "男"
else:
return "女"
#设置页面列的名称
gender.short_description = "性别"
list_display = ['pk', 'sname', 'sage', gender, 'scontend', 'sgrade', 'isDelete']
actions_on_bottom = True
actions_on_top = False
#admin.site.register(Students, StudentsAdmin)
#注释掉那个,在下面的类的头上加一个@admin.register(Students)
@admin.register(Students)
class StudentsAdmin(admin.ModelAdmin):
def gender(self):
概述:在Django中,视图对web请求进行回应,视图就是一个python函数,在views.py文件(在你的应用的文件夹下)中定义
有多少视图呢,一般来说有几个页面就有几个视图
也就是定义函数。在应用名目录下的views.py添加一下
from django.http import HttpResponse
#这里的request就是请求集,也就是浏览器给服务器的东西
def index(request):
return HttpResponse("Weclome to my chamber")
#返回给浏览器什么东西,我们现在没学模板就返回一串文本
我们在输入网址后,网址要给url控制器,给其匹配,我们则在需要配置视图,然后配置url。
所以流程即:定义视图——配置url
配置url:修改你的项目名目录下的urls.py文件——在myapp1(你的应用目录下)创建一个urls.py文件
在项目名中的urls.py中加入
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp1.urls')),
]
在新建的urls.py中加入
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index)#r防止字符被转义,^表示内容,$表示结束符
]
整个流程解释:我们的视图定义,需要配置,我们可以直接配置在应用目录下的urls.py中,但是为了隔离性,我们就在应用目录下创建一个urls.py,在这个里面调用那个视图,然后在外面的urls.py中包括上面的视图。我们以后在修改url的时候就直接在里面修改就行了,外面不需要再改了。
概述:模板是HTML页面,可以根据视图中传递过来的数据进行填充
在你的项目的根目录下创建:yaobinbin/templates/myapp1(注意这里的templates是和manage.py同级的)
修改settings.py中的TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'templates')],
需求:当你键入网址/grades的时候显示所有的班级,
模板语法:1){{输出值,可以是变量,对象.属性}} 2){%执行代码段%}
下图是grades.html的代码
班级信息
班级信息列表
{# [python04,python05,python06]对象,这里会创建一个循环,每次循环创建一个li#}
{% for grade in grades %}
{# 这个grade.gname可以是python的变量,也可以是对象.属性,条件判断得用大括号百分号这种,加了个"#"就是表示后面变量在网页里面是可以点的,并且网页会跳转到你指定的地方#}
{{grade.gname}}
{% endfor %}
from .models import Grades,Students
def grades(request):
#去模板里面取数据
gradesList =Grades.objects.all()
#将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器
return render(request, 'myapp1/grades.html', {"grades": gradesList})
#上面的大括号里面的grades就是给html的变量
url(r'^grades/$', views.grades),
1.修改grades.html
{# 这个grade.gname可以是python的变量,也可以是对象.属性,条件判断得用大括号百分号这种,加了个"#"输入之后网页地址会变#}
{{grade.gname}}
2.定义视图
def gradeStudents(request, num):
#获得对应的班级对象
grade = Grades.objects.get(pk=num)
#获得班级下所有的学生列表
studentList = grade.students_set.all()
return render(request, 'myapp1/students.html', {"students": studentList})
3.配置url
url(r'^grades/(\d+)$',views.gradeStudents)
#这个(\d+)是数字
注意:当你增加一张表的时候,直接重新迁移文件,执行迁移即可。但是如果你要修改字段,最好直接删表,重新迁移
Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一调用api,可以根据不同的业务需求选择不同的数据库
配置数据库:工程目录下的__init__.py文件加入两行代码——>在setting.py文件中修改——>定义模型类——>执行迁移生成数据表——>使用模型进行增删改查(crud)操作。
ORM:对象、关系、映射。它的作用就是把我们的CRUD操作转换成对应数据库的操作
根据对象的类型生成表结构;按对象、列表的操作转换为sql语句;将sql语句查询到的结构转换为对象、列表
极大的减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码
一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表的一个字段
属性命名限制:遵循标识符规则;由于Django的查询方式,不允许使用连续的下划线
逻辑删除:对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为FALSE
字段类型:
AutoField
一个根据实际ID自动增长的IntegerField,通常不指定。如果不指定,一个主键字段将自动添加到模型中
CharField(max_length=字符长度)
字符串,默认的表单样式是TextInput
TextField
大文本字段,一般超过4000使用,默认的表单控件是Textarea
IntegerField
整数
DecimalField(max_dights=None, decimal_places=None)
使用python的Decimal表示的十进制浮点数
参数说明:DecimalField.max_dights 位数总数
DecimalField.decimal_places 小数点后的数字位数
比如3.1415926的max_dights是8位,decimal_places是7位
FloatField
用python的float实例来表示的浮点数
BooleanField
True/False 字段,此字段的默认表单控制是CheckBoxInput
NullBooleanField
支持Null、True、False三种值
DataField[auto_now=False,auto_now_add=False])
使用Python的datatime.data实例表示的日期
参数说明:
DataField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于最后一次修改的时间戳,它总是使用当前日期,默认为false
DataField.auto_now_add当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
说明:auto_now,auto_now_add,and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果
TimeField
使用python的datatime》time实例表示的时间,参数同DataField
DataTimeField
使用python的datetime.datetime实例表示的日期和时间,参数同DateField
FileField
一个上传文件的字段
ImageField
继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项:通过字段选项,可以实现对字段的约束,在字段对象时通过关键字参数指定
null,blanke(如果未True,则该字段允许为空白,默认值为False),注意null是数据库范畴的概念,blank是表单验证范畴的。db_column字段的名称,如果未指定,则使用属性的名称,db_index若值为True,则在表中会为此字段创建索引,default默认值。primary_key主键设置。unique如果未TRUE,这个字段在表中必须有唯一值
ForeignKey:一对多,将字段定义在多的端中
ManyToManyField:多对多,将字段定义在两段中,再来一张表。
OneToOneField:一对一,将字段定义在任意一端中
格式:对象.模型类小写_set
示例:grade.students_set
格式:对象.模型类小写
示例:grade.students
格式:对象.属性_id
示例:student.sgrade_id
在模型类中定义Meta类,用于设置元信息
db_table:定义数据表名,推荐使用小写字母,如果我们不写,数据表名默认项目名小写_类名小写
ordering:对象的默认排序字段,获取对象的列表时使用
class Meta:
db_table = "grades"
ordering=['id']#这是以id为升序取出
ordering=['-id']#这是以id为降序取出
注意:排序会增加数据库的开销
类属性、创建对象
类属性:隐藏的类属性:objects是manage类的一个对象,作用是与数据库进行交互。当定义模型类里没有指定管理器,Django为模型创建一个名为objects的管理器。
#自定义模型管理器
stuObj = models.Manager()
此时objects管理器就不存在了
模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器
向管理器类中添加额外的方法;修改管理器返回的原始查询集。:重写get_queryset()方法
#注意这个Manager是大写的m
class StudentsManger(models.Manager):
def get_queryset(self):
return super(StudentsManger,self).get_queryset()\
.filter(isDelete=False)
#这个filter是将符合条件的过滤进来
#这是学生表
class Students(models.Model):
#自定义模型管理器
stuObj = models.Manager()
stuObj2 = StudentsManger()
这里是自定义模型管理器,可以不显示isDelete=True的用户
def students(request):
studentsList = Students.stuObj2.all()
return render(request, 'myapp/students.html', {"students": studentsList})
#urls.py文件
url('^students/$', views.students),
#通过调用stuObj2管理器就能将isDelete为真的过滤掉
目的:想数据库中添加数据;
当创建对象时,django不会对数据库进行读写操作,当调用save()方式时才与数据库交互,将对象保存到数据库表中
注意:__init__方法已经在父类models.Model中使用。在自定义的模型中无法使用。
方法:在模型类中增加一个类方法或者在自定义管理器中添加一个方法
方法一:在模型类中增加一个类方法
#这个是在models.py文件中
#定义一个类方法创建对象
@classmethod
def createStudent(cls, name, age, gender, content,
grade, lastTime, createTime, isD=False):#这个cls就代表了Students这个类
stu = cls(sname=name, sage=age, sgender=gender, scontend=content,sgrade=grade,
last_time=lastTime, create_time=createTime, isDelete=isD)
return stu
#这个是在views.py中
def addstu(request):
grade = Grades.objects.get(pk=1)
stu = Students.createStudent("大黄", 34, True, "my name is huang", grade,
"2017-8-10", "2017-5-6")
stu.save()
return HttpResponse("成功")
#这个是在urls.py中
url(r'^addstu/$', views.addstu),
方法二:在自定义管理器中添加一个方法
#models.py中
def createStu(self, name, age, gender, content,
grade, lastTime, createTime, isD=False):
stu = self.model()
#print(type(grade))
stu.sname = name
stu.sage = age
stu.sgender = gender
stu.scontend = content
stu.sgrade = grade
stu.last_time = lastTime
stu.create_time = createTime
return stu
#views.py中
def addstu2(request):
grade = Grades.objects.get(pk=1)
stu = Students.stuObj2.createStu("小黄", 24, True, "my name is huang", grade,
"2018-8-10", "2017-5-6")
stu.save()
return HttpResponse("成功")
#urls.py中
url(r'^addstu2/$', views.addstu2),
查询集:表示从数据库获取的对象集合
查询集可以有多个过滤器(我的查询集是有这个对象的所有数据,而我要的不是所有的数据而是固定的数据)
过滤器就是一个函数,基于所给的参数限制查询集结构
从sql角度来说,查询集和select语句等价,过滤器就像where条件
在管理器上调用过滤器方法返回查询集;查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用;惰性执行:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据;
直接访问数据的情况:迭代、序列化、与if合用;
all()、
filter():filter(键=值,键=值)或者filter(键=值).filter(键=值);这个是且的关系;保留符合条件的数据
exclude():过滤掉符合条件的数据
order_by():排序
values():一条数据就是一个对象(字典),返回一个列表
get():返回一个满足条件的对象;注意:如果没有找到符合条件的对象,模型类会引发一个异常模型类.DoesNoteExists异常。如果找到多个对象,也会引发异常:模型类".MutipleObjectsReturned"异常
count():返回当前查询集中的对象个数;first():返回查询集中的第一个对象;last():返回查询集中的最后一个对象;
exists():判断查询集中是否有数据,如果有数据返回True
查询集返回列表:可以使用下标的方法进行限制,等同于sql中的limit语句。注意下标不能是负数
#views.py
def students3(request):
studentsList = Students.stuObj2.all()[0:3]
return render(request, 'myapp/students.html',
{"students": studentsList})
#urls.py
url('^students3/$', views.students3),
需求:根据你输入地址的数量显示数量
#views.py
#分页查询,每一页显示固定个数
def stupage(request, page):
#0-3 3-6 6-9
#1 2 3
page = int(page)
studentsList = Students.stuObj2.all()[(page-1)*3:page*3]
return render(request, 'myapp/students.html',
{"students": studentsList})
#urls.py
url('^students/(\d+)/$', views.stupage),
概述:每个查询集都包含一个缓存,来最小化的对数据库访问;在新建的查询集中,缓存首次为空,第一次对查询集求值(取数据时),会发生数据缓存,Django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存
概述,比较运算符,聚合函数,F对象,Q对象
实现了sql中的where查询,作为方法filter(),exlcude(), get()的参数;
语法:属性名称__运算符 = 值 (两个下划线)
外键:属性名.id; 转义:sql的like是使用%作为占位符。如何匹配数据中的%,就要使用转义
转义使用:filter(sname__contains=%),就可以直接匹配不用转义
比较运算符:exact:判断,大小写敏感;contains:是否包含
studentsList = Students.stuObj2.filter(sname__contains="黄")
startswith和endswith:以value开头或结尾,大小写敏感
studentsList = Students.stuObj2.filter(sname__startswith="大")
以上四个在前面加上一个i就表示不区分大小写,iexact、icontains、istartswith、iendswith
isnull和isnotnull;in是否包含在范围内
studentsList = Students.stuObj2.filter(pk__in=[1, 3, 5])
gt、gte、lt、lte:分别对应大于、大于等于、小于、小于等于
studentsList = Students.stuObj2.filter(sage__gt=22)
year、month、day、week_day、hour、minute、second:日期
studentsList = Students.stuObj2.filter(last_time__year=2019)
语法:模型类名__属性名__比较运算符
#描述带有‘大黄’的名字的学生是哪个班级的
grade = Grades.objects.filter(
students__scontend__contains='大黄'
)
pk:主键
使用aggregate()函数返回聚合函数的值
Avg、Count、Max、Min、Sum
from django.db.models import Max,Min
maxAge = Students.stuObj2.aggregate(Max('sage'))
print(maxAge)
可以使用一个模型的A属性与B属性进行比较(一个表中的两个属性进行比较)
from django.db.models import F,Q
def grades(request):
g = Grades.objects.filter(ggirlnum__lt=F('gboynum'))
print(g)
return HttpResponse("0000000")
支持F对象的数据运算
g = Grades.objects.filter(ggirlnum__lt=F('gboynum')+20)
概述:过滤器的方法中的关键词参数。条件为And模式
需求:进行or查询。使用Q对象。即求并集
from django.db.models import F,Q
studentsList = Students.stuObj2.filter(Q(pk__lte=6) | Q(sage__gt=50))
return render(request, 'myapp/students.html',
{"students": studentsList})
#如果单纯是下面这种情况就是单纯的匹配了
studentsList = Students.stuObj2.filter(Q(pk__lte=6))
#studentsList = Students.stuObj2.filter(~Q(pk__lte=6))这种就是把上面那种取反
Django在urls.py里面设置namespace的时候注意:https://blog.csdn.net/weixin_40841752/article/details/79335345
#settings设置
DEBUG = False
ALLOWED_HOSTS = ['*']
#另外注意要在templates目录下直接新建404.html文件。还注意templates路径设置。这样设置即可
#还有关于request_path参数
#urls.py中设置
url(r'^get1', views.get1),
url(r'^get2', views.get2),
#views.py中设置
def get1(request):
a = request.GET.get('a')
b = request.GET.get['b']#这种方式也是可以的
c = request.GET.get('c')
return HttpResponse(a+" "+b+" "+c)
def get2(request):
a = request.GET.getlist('a')
a1 = a[0]
a2 = a[1]
c = request.GET.get('c')
return HttpResponse(a1 + " " + a2 + " " + c)
#项目目录下的urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path(r'huaq/', include(('myapp.urls', 'myapp'), namespace="myapp")),
]
#注意那个huaq不能用bin这样特殊关键词,要不然不会生成动态链接
#应用目录下的urls.py
url(r'showregist/$', views.showregist),
url(r'regist/$', views.regist),
#regist.html
#views.py中
def showregist(request):
return render(request, 'myapp/regist.html')
def regist(request):
return HttpResponse("啊哈哈哈哈成功")
#注意:html的修改要重新启动服务器才会生效
注意这里的hobby由于是checkbox,其传入的数据不止一个,所以要用getlist来接收
hobby = request.POST.getlist("hobby")
#注意表单提交的usrf的关闭(在settings.py中注销中间组件:
#'django.middleware.csrf.CsrfViewMiddleware',
)
HttpResponse属性查看:
#views.py
def showresponse(request):
res = HttpResponse()
res.content = "U are good"
print(res.content)
print(res.status_code)
print(res.charset)
return res
#输出
b'U are good'
200
utf-8
cookie使用
def cookietext(request):
res = HttpResponse()
cookie = request.COOKIES
#res.write(""+cookie["binbin"]+"
")
cookie = res.set_cookie("binbin", "good")
return res
#第一次写入cookie:key为"binbin",值为"good"
def cookietext(request):
res = HttpResponse()
cookie = request.COOKIES
res.write(""+cookie["binbin"]+"
")
#cookie = res.set_cookie("binbin", "good")
return res
#第二次取出cookie并使用
第二次页面输出:记住:以后我们再去发生请求,都会带着这个cookie。对于我这个服务器只能使用"binbin"。
说明:假如你注册好了, 你登陆了,我就给你返回一个cookie,那么这个cookie我就能给你存一个token值(一个键对应一个token值),那么以后你再发生请求了,服务器接收你的请求,先拿出cookie,找到对应的token值,先验证token值,验证成功就能登陆了。删除cookie删除对应的键就行了
你输入一个网址之后,让其自动转到另外一个view那里去。
#重定向
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
def redirect1(request):
return HttpResponseRedirect('/huaq/redirect2')
#return redirect('/huaq/redirect2')
def redirect2(request):
return HttpResponse("我是重定向之后的视图哦")
#第二个redirect(to)是简写
session实现登陆用户返回登陆页面信息记录
#views.py
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
def redirect1(request):
return HttpResponseRedirect('/huaq/redirect2')
#return redirect('/huaq/redirect2')
def redirect2(request):
return HttpResponse("我是重定向之后的视图哦")
def main1(request):
#取session,要用session.get而不是POST.get
username = request.session.get('name', "游客")
print(username)
return render(request, 'myapp/main.html', {'username': username})
def login(request):
return render(request, 'myapp/login.html')
def showmain(request):
print("****")
#这个username是从html里面POST过来的变量名即:name值
username = request.POST.get('username')
#存储session
request.session['name'] = username
# 注意这个路径
return redirect('/huaq/main1/')
#main.html
我的
欢迎:{{ username }}
登陆
#login.html
Title
#urls.py
url(r'^main1/$', views.main1),
url(r'^login/$', views.login),
url(r'^showmain/$', views.showmain),
#注意这个“^”号一定要加,要不然遇到main的时候,会直接匹配到main1(我最开始是main,会有变化,main1没影响)而不是showmain。!
url:反向解析
主项目目录下的url的namespace和url对应的名字结合,放到模板中,他就会自动生成对应的链接在你指定的链接后面,动态。
#主项目url
path('', include('myapp.urls', namespace="myapp")),
#应用内url
url(r'^good/(\d+)/$', views.good, name="good"),
#index.html
链接
链接
这里使用了url反向解析,就会根据命名空间+name组合生成。并且后面的参数和前面记得要有一个空格
点击链接后跳转页面:http://127.0.0.1:8000/good/1/