django(4)

1、django的简介
django(4)_第1张图片

浏览器与服务器之间遵循的一个协议: HTTP协议

服务器与应用程序框架之间:wsgi

1.1 Django的简介

Django是一个重量型框架

主要目的:简便快捷开发

Django基于MVC模式,但是它是MVT模式的

核心:解耦(高内聚,低耦合)
django(4)_第2张图片
django(4)_第3张图片

MVC设计的框架

(1)重量级框架

(2)MVT模式

MVC :

定义:

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
django(4)_第4张图片

2、创建项目的环境

虚拟环境:

项目所需要的第三方软件环境相互隔离

安装虚拟环境

sudo pip3 install virtualenv
sudo pip3 install virtualenvwrapper

创建虚拟环境

mkvirtualenv dj_3 -p python

切换虚拟环境

workon dj_3

删除虚拟环境

rmvirtualenv dj_3

退出环境

deactivate

3、安装Django,初步讲解

3.1安装Django:

pip install django==安装的版本号
一般安装在虚拟环境中

3.2创建项目:

django-admin startproject 项目名称
里面有一个和项目同名的文件夹,内部包含的是项目的配置文件
settings.py项目的整体配置文件
urls.py项目的URL配置文件
wsgi.py是项目与服务器的入口

manage.py是项目运行的入口

3.3 运行服务器

python manage.py runserver
注意点:如果不指定端口,默认是8000
python manage.py runserver 5000

3.4 成功的界面:
django(4)_第5张图片

3.5 创建模块

python manage.py startapp 模块名

user子模块

admin.py 后台管理站点的配置

apps.py 当前子应用的信息

models.py 保存书写的数据库模型

text.py 用来保存开发测试用例的,进行单元测试

views.py 书写逻辑,用来保存视图。

3.6 创建模块之后,注册子模块,注册到同名文件夹的setting中

pai0805中的settings.py

INSTALLED_APPS = [
	"django.contrib.admin",
	"django.contrib.auth",
	"django.contrib.contenttypes",
	"django.contrib.sessions",
	"django.contrib.messages",
	"django.contrib.staticfiles",
	"user.apps.UserConfig"

]

3.7 简单体验数据库交互

3.7.1 定义表与字段

一张表对应了一个类

user中models.py

class UserInfo(models.Model):
	name = models.CharField(max_length=10)
	age = models.IntegerField()
	phone = models.CharField(max_length=11)
	
	def __str__(self):
	return self.name
	
	
类名对应的是表名
属性名对应的是字段名
注意点:继承于Model

3.7.2 迁移数据库表

1、生成迁移文件
python manage.py makemigration
2、执行迁移文件
pyhton manage.py migrate
迁移成功并且执行迁移之后,才真正在数据库产生表

3.7.3 创建超级权限账号和修改界面语言

pai0805中的settings.py



LANGUAGE_CODE = "zh-Hans"

TIME_ZONE = "Asia/Shanghai"

python manage.py createsuperuser

3.7.4 数据库的配置

1、设置数据库

pai0805中的settings.py

DATABASES={
	"default":{
		"ENGINE":"django.db.backends.mysql",#这个参数是设置数据库
		"NAME":"数据库名字",#使用的数据的名字
		"USER":"root",#数据库的用户名
		"PASSWORD":"mysql",
		"HOST":"127.0.0.1",#数据库主机的地址
		"PORT":3307,#数据库的端口
}
}

2、添加驱动

pai0805中的 __init__.py

import pymysql

pymysql.install_as_MySQLdb()

3、在admin站点管理中注册models

user 中 admin.py

from django.contrib import admin
from user.models import UserInfo  #导入

admin.site.register(UserInfo)

3.7.5 查看

use pai0805;

show tables;

django(4)_第6张图片

其中user_userinfo表是创建的

3.8 实现网站的用户信息展示

3.8.1 定义视图,处理业务

user中view.py
视图的作业:创建业务逻辑,完成路径--视图的匹配,返回给对应路径的数据或者网页
视图函数
def userinfo():
	"""这个视图函数实现的是暂时用户的信息,匹配的路径/userinfo"""
	pass
	
def index(request):
    print("----------------------")
    print(type(request))
    print(request)
    # return "hello world"
    return HttpResponse("hello world")


Request是一个请求对象,可以是别的名字,但是一般是request,每一个视图函数都必须要有一个参数来承接

报错:
在这里插入图片描述

注意点:视图函数必须要有一个响应对象返回
在这里插入图片描述

视图函数,至少需要一个参数来接收Django传递过来的参数

3.8.2 配置路由URL

1、路由配置第一种方法:

from user import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^index/$",views.indesx),
]

2、第二种方法(分模块再集中)

(1)在项目所在的同名文件夹的urls里面配置include()将各个模块的URL加载

(2)在各个模块的URL里面进行配置URL-----VIEWS

(3)项目同名的urls值完成路由的分发匹配过程

真正匹配路径在各个模块的URL下面

视图与路径的匹配

同名文件夹中的urls.py中

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^book/",include("book.urls")),
    url(r"^user/",include("user.urls")),
    url(r"^username/",include("username.urls")),
]
各个子模块的urls.py中
from django.conf.urls import url
from username import views


urlpatterns = [
    url(r"(?Pcity)/(?P\w+)/",views.username),
    url(r"^huoqu/",views.huoqu),
    url(r"^search/$",views.search),
    url(r"^data/$",views.data),
]

3.9 配置html模板文件

3.9.1 创建一个名字叫templates的文件夹

3.9.2 配置文件夹的查找路径

在同名文件夹中settings.py中的
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',
            ],
        },
    },
]

3.9.3 返回模板到前端

def show(request):
    # #创建连接
    # con = pymysql.connect(host="localhost", user="root", password="535897", database="pai0805_2", port=3307,charset="utf8")
    # #获取光标对象,操作句柄
    # cur=con.cursor()
    # #写查询语句
    # sql1="select * from user_userinfo;"
    # #进行查询
    # ret_num1 =cur.execute(sql1)
    # ret = cur.fetchall()
    # return HttpResponse(ret)
    from user.models import UserInfo

    data = UserInfo.objects.all()
    for i in data:
        print(i)
	#可以在info.html中设置界面的字体,格式
    return render(request,"info.html",{"data":data[0],"data1":data[1]})
  1. 模型的增删改查(ORM模块)

4.1 数据的查询

4.1.1 查询所有的数据

from user.models import UserInfo

data = UserInfo.objects.all()

格式: 模型类名.objects.all()

查询多条数据

4.1.2 按照指定条件查询

def get(self,*args,**kwargs):
	
注意点:
1、get()获取的是指定条件符合数据,只有一条

4.1.3 计数语句

data = Userinfo.objects.count()
返回的是数据的条数

4.1.4 符合条件的多条数据查询

1、比较查询

符合条件的多条语句
1、比较查询  大于 gt greater then
data = UserInfo.objects.filter(id_gt = 1)
id大于等于3 gte
data = UserInfo.objects.filter(id_gte = 3)
id小于1的人
data = UserInfo.objects.filter(id_lt=1)
id小于等于1的人
data = UserInfo.objects.filter(id_lte=1)

注意点:
filter既可以查询一条语句,也可以查询多条语句
但是查询的结果放在一个列表里面、
如果查询不到任何满足条件的数据,则返回的是一个空列表

2、模糊查询

查找名字中带有王的人
data = UserInfo.objects.filter(name_contains = "王")

查找姓王的人
data = UserInfo.objects.filter(name_startswith = "王")

4.1.5 关于外键的查询

book_obj = BookInfo.objects.filter(personinfo__name__exact="猴子")
print(book_obj)

per_obj =  PersonInfo.objects.filter(book__seltcount__gt=0)
print(per_obj)
注意点
#关联模型类的小写--属性名--条件筛选运算符=值

4.1.6 F()、Q()

#F()解决属性与属性的对比
    #Q()表示逻辑关系
    # ret1 = BookInfo.objects.filter(count__gt=F("seltcount"))
    # print(ret1)
    ret2 = BookInfo.objects.filter(seltcount__exact=F("count")*2,seltcount__gt=0)
    print(ret2)

    ret3 = BookInfo.objects.filter(seltcount__exact=F("count") * 2).filter(seltcount__gt=0)
    print(ret3)

    # ret4 = BookInfo.objects.filter(seltcount__exact=F("count") * 2, seltcount__gt~Q)
    # print(ret4)
    ret5 = BookInfo.objects.filter(Q(seltcount__exact=0)&Q(seltcount__exact=5))
    print(ret5)


注意点:
F()对象是用来表示两个属性之间的对比
Q()对象用来表示各个关系的与或非的操作,&  |  ~

4.2 数据的增加

4.2.1 第一种方式

通过创建对象,进行属性设置,最后再保存的方式

 book1 = BookInfo(booknane="红楼梦",time="1700-1-1")
 book1.save()

4.2.2 第二种方式(重点)

 PersonInfo.objects.create(name="猴子",weapon="棒子",book=book1[0])

4.3 当数据表存在数据的时候,对于修改数据表

第一种
book2 = BookInfo.objects.get(pk=3)
book2.time="1973-1-1"
book2.save()

第二种
BookInfo.objects.filter(name="三国演绎").update(time="1973-10-01")

4.4关于数据库表名的设计

如果没有指定数据库的表名,则MYSQL中会以应用名_模型类名的小写作为数据库的表名

设计数据库表名:

在模型类的内部进行表的设计

class PersonInfo(models.Model):
    gender_choice = (
        (0,"boy"),
        (1,"girl"),
    )

	#名字
    name = models.CharField(max_length=30,verbose_name="人物名字")
	# 性别
    gender = models.SmallIntegerField(choices=gender_choice,default=0,verbose_name="性别")
	# 武器与技能
    weapon = models.CharField(max_length=300, verbose_name="武器")
	# 逻辑删除
    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")

    book = models.ForeignKey(BookInfo,on_delete=models.DO_NOTHING,verbose_name="外间图书")

    def __str__(self):

        return self.name
    class Meta:
        db_table = "personinfo"
        #指定数据库的表名
        verbose_name = "人物信息"
        #修改后台管理中心中数据库表的名字
        verbose_name_plural=verbose_name
        #将复数形式去除
        
注意点:
修改数据库的表名需要迁移

4.5 关于模型与数据库数据的关系

from book.models import BookInfo,PersonInfo#测试的时候,需要将使用到的模型导入

add = BookInfo(name="书名",time="出版")#数据库的一条数据,其实就是模型类的一个实例
add.save()#保存,不保存不生效

当存在外键的时候:

person1 = PersonInfo()
person1.name="名字"
person1.book = add
person1.save()
Addinfo这个属性是一个外键,赋值的时候需要以对象进行赋值

4.6 关于orm模块设置数据类型
在这里插入图片描述

约束

primary_key = False 主键
null = False 允许为空,默认为false,数据库的角度来说的
blank = False 字段允许为空白,表单验证
db_column = None字段的名称,没有指定的话,使用属性的名字
db_index=Flase给该字段设置索引
unique =Flase 说明该字段在这个表里面具有唯一性
delfault = 设置默认值

例子:设置字段名字
在这里插入图片描述

4.7 模型的相关字段

name = models.CharField(db_column="username",max_length=20)
phone = models.CharField(max_length=11,unique=True)
pwd = models.CharField(max_length=8,default="123")
pwd= mdoels.IntegerField(default="123")
models.AutoField()如果不指定,则自动指定属性名为id的自增长属性,一般不指定
models.BooleanField()布尔值
models.NullBolleanField()布尔值加null
models.TextField()大文本字段,字符在4000向上
models.DecimalField(max_digits=总位数,decimal_places=小数位数)#十进制浮点型
models.DateField()表示的是日期
models.TimeField()表示的是时间
models.DateTimeField()表示的是日期加时间
models.FileField()上传文件的字段
models.ImageField()对上传的文件进行校验,保证是有效图片

5、视图与模型的结合使用

以简单的用户注册为例

5.1 设计展示用户操作页面

请输入用户名: 请输入用户密码:

5.2 设置页面对应的路径,当用户请求的时候,展示
在这里插入图片描述

注意点:视图函数至少有一个参数

必有要有响应对象返回

return HttpResponse("ok")

5.3 HTTP请求对象

def index(request):
	print(request)
	return HttpResponse("123")

注意点:

1、这是一个HTTP请求对象

2、这个请求对象里面封装的是请求信息,包括请求的方式,数据等

5.3.1 request.body

当非表单数据,request.body 来获取到请求体数据,但是,body获取的数据是bytes类型

def index(request):
	print(request.body)
	return HttpResponse("123")
	
一般情况下,都是json

5.3.2 request.GET

获取到的都是类字典类型

5.3.3 request.POST

获取到的都是类字典类型

5.3.4 request.META获取请求头的数据

def index(request):
	print(request.META)
	requset.META这个属性,用来获取的是请求头header部分所有的数据
	他是一个字典类型

5.4 httpresponse对象

5.4.1 render函数的具体使用

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

注意点:

1、 Render函数适用的范围是:有网页,有填充网页的数据

2、 Render这个函数的第一个参数是当前路径的请求对象

3、 Context这个参数指向的是填充网页的数据,注意它的格式必须是字典

5.4.2 HTTPresponse

def __init__(self, content_type=None, status=None, reason=None, charset=None):
        # _headers is a mapping of the lower-case name to the original case of
        # the header (required for working with legacy systems) and the header
        # value. Both the name of the header and its value are ASCII strings.
        self._headers = {}
        self._closable_objects = []
        # This parameter is set by the handler. It's necessary to preserve the
        # historical behavior of request_finished.
        self._handler_class = None
        self.cookies = SimpleCookie()
        self.closed = False
        if status is not None:
            try:
                self.status_code = int(status)
            except (ValueError, TypeError):
                raise TypeError('HTTP status code must be an integer.')

            if not 100 <= self.status_code <= 599:
                raise ValueError('HTTP status code must be an integer from 100 to 599.')
        self._reason_phrase = reason
        self._charset = charset
        if content_type is None:
            content_type = '%s; charset=%s' % (settings.DEFAULT_CONTENT_TYPE,
                                               self.charset)
        self['Content-Type'] = content_type

注意点:

1、适用范围,返回的是让浏览器或者客户端展示的字符串

5.5 csrf的问题

5.5.1 在表单中增加

请输入用户名: 请输入用户密码:

5.6 关于路径匹配的补充知识

5.6.1 路径匹配

url(r"^userna(\w+)/",views.username),
url(r"^huoqu/",views.huoqu),

Exception Value:	
username() takes 1 positional argument but 2 were given

URL函数正则匹配,如果需要匹配组,则匹配出来的组信息,会自动传递给对应的视图函数

url(r"^userna(\w+)/"[0],views.username),

5.6.2 关键字参数

urlpatterns = [
    url(r"(?Pcity)/(?P\w+)/",views.username),
    url(r"^huoqu/",views.huoqu),
    url(r"^search/$",views.search),
    url(r"^data/$",views.data),
]

def username(request,city,cname):
    # #创建连接
    # con = pymysql.connect(host="localhost", user="root", password="535897", database="pai0805_2", port=3307,charset="utf8")
    # #获取光标对象,操作句柄
    # cur=con.cursor()
    # #写查询语句
    # sql1="select * from user_userinfo;"
    # #进行查询
    # ret_num1 =cur.execute(sql1)
    # ret = cur.fetchall()
    # return HttpResponse(ret)
    print(city)
    print(cname)
    return render(request,"register.html")

注意点:?P

5.7 查询对象的获取

try:
    book = BookInfo.objects.get(name="三国演绎")
except Exception as e:
	print(e)
#通过书籍查找该书籍查找该书籍中的人物
print(book)
peo = book.personinfo_set.all()
print(peo)
obj = PersonInfo.objects.get(name="猴子")
print(obj.book.id)
print(type(obj.book))
#关联过滤查询

book_obj = BookInfo.objects.filter(personinfo__name__exact="猴子")
print(book_obj)
#关联模型类的小写--属性名--条件筛选运算符=值
per_obj =  PersonInfo.objects.filter(book__seltcount__gt=0)
print(per_obj)

注意点:

1、request。GET\POST 获取的都是QUERYDICT对象

2、获取QueryDict的某一个值对应的对象,使用的是get ,但是如果一个键名对应多个值的时候,get只能获取一个,并且是最后一个

3、如果想要获取多个值,需要使用的是getlist

4、get \getlist 都可以设置默认值,当获取不到数据的时候(当键名不存在获取或者getlist获取到空列表的时候)

5.8 form表单的提取

注意点:

当name值相同的时候,可以设置value的值

5.9 关于浏览器与服务器之间的状态保持

浏览器与服务器之间是无状态的

Ssession:存在服务器一端

Cookie:存在浏览器一端

关系:一一对应的

5.9.1 cookie

特点:

1、键值结构

2、cookie是基于域名安全的,不同域名之间cookie是不可以进行相互的访问的

3、当浏览器请求某一个网站,会将与当前网站所有的cookie提交给服务器

4、cookie数据不允许存储敏感信息,密码,支付宝密码

5.9.2 cookie的设置
django(4)_第7张图片

设置完成之后:
django(4)_第8张图片

创建cookie

Response.set_cookie()

删除cookie

Resposne.delete_cookie()

读取cookie

Request.COOKIES.get(键名)

Cookie虽然存储在浏览器一端,但是,它是在服务器一端进行设置的,

5.9.2 session

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

1、如果需要使用数据库存储session,安装应用

'django.contrib.sessions',

2、在数据库中

注意点:在Django项目中,session的引擎没有设置,因为则是默认的存储方式

你可能感兴趣的:(django(4))