Django框架基础

1.Django框架

1.什么是Django框架

​ 是一个开源框架,在2005年发布,早起用来开发新闻类网站;

2.Django优点

​ 1.开源,有完美的文档支持

​ 2.解决方案多,内部功能强大

​ 3.提供了完整的路由系统

​ 4.自助式后台管理

3.Django的安装

1.Linux中的安装

1.查看已安装的Django

1.进入虚拟环境

​ 2.进入python交互模式下

​ 3.在交互模式中数据

​ 1.import Django

​ 无反应,已经安装好

​ 报错:环境中没有Django

​ 2.Django.VERSION 查看版本

​ 2.安装Django

​ 1.在线安装 ----pip

​ 1.pip install Django==1.11.8

​ 2.离线安装

​ 1.下载所需要的Django包

http://www.djangoproject.com

​ download

​ 2.在Linux中解压Django包

​ tar -xvf Django-1.11.8.tar.gz

​ 3.进入到Django-1.11.8中

​ python setup.py install

​ 2.在Windows中安装

​ 1.在线安装

pip3 install Django

4.Django使用

​ 1.创建Django项目

django-admin.py startproject 项目名

也可以在pyChram点击创建Django项目按钮

2.通过manage.py 启动

进入项目目录下

python manage.py runserver或

python manage.py runserver 0.0.0.0:80

5.Django 的结果介绍

1.manage.py 文件

负责执行Django中的各项目操作的文件

如: 启动服务、创建应用、创建管理员,创建用户

2.主文件夹中的内容

1.init.py

项目初始化文件,每当启动项目时,自动执行

有初始化文件,放在此处如果使用的是MySQL服务器需要在此配置如下:

import pymysql

pymysql.install_as_MySQLdb()

2.setting.py(重要文件)

项目的主配置文件

1.BASE_DIR:项目所在地绝对路径,一般默认 2.DEBUG:调试模式 开发过程中,推荐使用True, 上线运行时,推荐使用False, 3.ALLOWED_HOSTS 如果不设置,只有本地能访问。 通常推荐为“*” 4.INSTALLED_APPS 指定安装的应用,如果新建应用需要在此进行配置应用名称如:index 5.MIDDLEWARE:指定中间 6.ROOT-URLCONF:指定项目的基础路由配置文件 7.TEMPLATES:指定模板信息 8.DATABASES:制定数据库信息

9.LANGUGE_CODE:指定语言

一般改成中文编码:zh-Hans

10.静态路由地址 STATIC_URL = '/static/'

3.urls.py

项目路由配置文件

路由:去哪找执行文件

一般情况下的配置如下:path()

from django.urls import path

from .views import *
urlpatterns = [
    path('', index_views, name='index'),
    path('single/(?P<id>\d+)/', single_views, name='single'),
    path('single_class/(?P<name>\w+)/', single_class_views, name='single_class'),
    path('full-width/', full_width_views, name='full'),
    path('full-list/(?P<id>\d+)/', full_list_views, name='full_list'),
    path('about/', about_views, name='about'),
    path('contact/', contact_views, name='contact')
]

​ 4.wsgi.py

应用服务器配置,暂时不用

3.URL使用

1.urls.py

​ 默认自主文件下,包含所有请求地址到视图的映射

2.测试URL和视图

​ 1.在项目主文件夹创建views.py

​ 作用:包含所有定义好的视图

​ views.py

​ from django.urls import path

​ from django.http import HttpResponse

​ 2.在urls.py里面追加

​ from .views import *

3.path函数

path 函数语法

path(regex,views,kwargs=None,name=None)

1.regex

正则表达式,匹配请求的url

访问时的路由地址,可以加参数,参数需要进行正则校验;

​ 2.views

URL 处理的视图函数,自定义

views层对应的方法名,需要在里面实现页面的跳转;

3.kwargs

字典,向views传参时使用

​ 4.name

​ 字符串,给url起一个别名,在模板中使用

4.通过url向views传参

from django.urls import path
# 这是对应的path
path('index/(\d{4})/(\d{2})/(\d{2})',index_views)
# 这是对应的请求链接
http://localhost:8000/index/2018/07/11

3.Django 应用

1.什么是应用?

​ 应用就是网站中的独立模块

2.创建应用

​ 1.命令

​ ./manage.py startapp 应用名称

​ 2.在setting.py 中注册应用

​ INSTALLED_APPS=[

​ ...........

​ '应用名称',

​ ]

3.应用的结构

1.migrations 目录

​ 存放在数据库日志,是一个Django与数据库交互的中间件

​ 2.init.py

​ 应用的后台管理文件

​ 3.admin.py

​ 应用的后台管理配置文件

​ 4.app.py

​ 应用的属性配置文件,不需要改动

5.models.py

​ Models模型文件

6.tests.py

​ 测试模块,不需要改动

​ 7.views.py

定义视图的文件

4.Django应用
1.Django中的模板

1.什么是模板?

​ 就是一个网页,可被视图相应给用户

​ 2.模板设置

在setting中INSTALLED_APPS中需要加上应用名称

3.模板的加载方式

使用render或者render_to_response直接加载

return render(request,‘网页’,参数三)

参数三:一般可以为固定对象,也可以为列表对象,如果较多可以直接使用locals()

4.url()中的第四个参数

name:定义url的别名,允许在template中使用别名来访问url

在模板中,使用 name 加载

通过别名访问路径

5.模板语法

作用:允许将后端的数据传递给模板,在模板中显示实际变量的值

​ 在Django中允许传递给模板作为变量的类型

​ 数字,字符,列表,元组,字典,函数,对象

​ 如何将变量传到模板中:

​ 1.使用render加载模板

​ dic = {

​ ‘变量’:‘值’,

​ }

return render(request,'',dic)

2.标签

1.什么是标签,

允许嵌套一些服务器基本逻辑运算到模板中

​ 2.语法

​ {%%}

​ 3.常用标签

​ 1.{% if %}...{% endif %}

​ 2.{% if %}...{% else%}...{% endif %}

​ 3.{% ifequal %}...{% endifequal %}

​ 4.{% for 变量 in 列表|元组 %}

​ {{变量}}

​ {% endfor %}

​ 允许使用内置变量(免声明)

​ 变量:forloop

​ 属性:

​ 1.forloop:counter: 记录当前循环的次数

​ 2.forloop:counter0: 同上从0开始

​ 3.forloop:revcounter: 记录未被遍历的数量

​ 4.forloop:first: 布尔值标记是否第一个项目

​ 5.forloop:last: 布尔值,标记为最后一个项目

3.过滤器

​ 1.作用:

在显示变量中,允许对数据进行筛选或改变

​ 2.语法

{{ var | 过滤器}}

3.常用过滤器

​ 1.{{var | upper}}

​ 将var的数据变为全大写

​ 2.{{var | lower}}

将var的数据变为全小写

3.{{var | floatformat:n}}

将var四舍五入到n为小数

5.模板继承

1.模板的继承

​ 当多个模板具备相同的内容时,就可以使用继承的方式来简化代码的开发 当子模板继承父模板后,子模板会具备模板中所有的内容,并且可以修改或增加属于自己的内容

2.模板继承的语法

​ 1.在父模板中 增加{%block 名称%}....{%endblock%} 在block中定义的是正常显示在父模板中但允许被子模板修改的内容

​ 在父模板中{%block 名称%}...{%endblock%}允许出现若干个

​ 2.在 子模板 中 1.在最顶层的第一句话增加 {%extends '父模板的名称'%} 2.增加block标记, 编写属于自己的内容 {%block 名称%}   ... {%endblock%}

 

模型-models

1.什么是模型?

​ 按照数据库表结果来抽象出来的class在数据库中,可以完成对数据的CRUD

​ C: create

​ R: retrieve

​ U: update

D: delete

2.创建 和 使用模型 - ORM

​ 1.什么是ORM?

​ 中文:对象关系映射

​ 三大特征:

​ 1.数据表 到 类 映射

​ 允许将表自动生成一个class,也允许将类对应的自动生成表

​ 2.数据类型的映射

​ 允许将表中的字段自动生成到编程语言中 的属性,并能够将表中的字段的数据

​ 类型,也对应生成到编程语言中对应数据类型

​ 3.关系映射

​ 数据库的关联关系:

​ 一对一

​ 一对多

​ 多对多

​ 将表中的关联关系也映射到编程语言的class,通过创建对象的关系来完成映射

​ 2.ORM的优点

​ 1.提高了开发效率,能够自动完成class到table的映射或者table到class的映射,可以在程

​ 序中省略庞大的数据访问层

2.不用编写SQL,也能完成岁数据的CRUD操作

3.创建 和 配置 数据库

​ 1.数据库创建

​ create database webdb default charset utf8

​ 2.Django中数据库配置

​ 在setting中配置数据库信息

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'laboratory',
        'USER': 'root',
        'PASSWORD': 'mysql',
        'HOST': 'localhost',
        'POST': '3306',
        'OPTIONS': {'isolation_level': None}
    }
}

1.ENGINE:引擎

连接MySQL的引擎django.db.backends.mysql

​ 2.NAME:要连接的 数据库名

​ 3.USER:用户名名称,通常都是root

​ 4.PASSWORD:用户名密码:mysql

​ 5.HOST:主机名

​ 6.POST:端口号:3306

4.数据库的同步操作
  1. manage.py makemigrations

    在进行完models编写后在项目目录下使用该目录映射成py文件

作用将每个应用下的models先映射成数据库的日志文件,并存放在每个应用下的migrations

文件中

若报错:

在主目录下的init.py

import pymysql

pymysql.install_as_MySQLdb()

  1. manage.py migrate

作用:将每个应用下的migrations 文件夹中的日志文件同步到数据库

5.编写models

1.注意

​ 1.models中的每个class都成为模型类或者实体类

2.models中的每个实体类,必须继承自models.Model

​ 2.创建模型类

models.py

from django.db import models

class Publisher(models.Model):

​ name = models.CharField(max_length= 30)

​ address = models.CharField(max_length=50)

​ city = models.CharField(max_length=30)

​ country = models.CharField(max_length=30)

​ website = models.URLField()

6.Django提供的数据字段 和 字段选项

​ 1.数据字段

​ 1.BooleanField()

​ 2.CharField()

​ 3.DateField()

​ 4.DecimalField()

​ 5.EmailField()

​ 6.FloatField()

​ 7.fileField()

​ 8.IntegerField()

​ 9.ImageField()

​ 10,URLField()

​ 2.字段选项

​ 1.null:是否允许为空

​ name=models.CharField(max_length=30,null=True)

​ 2.default:为列设置默认值

​ name=models.CHarField(max_length=30,default='匿名')

​ 3.verbose_name:在后台管理中,该列显示的名称

​ name=models.CHarField(max_length=30,verbose_name=‘用户名称’)

举个栗子:

# 文章表的创建
class ARTICLE(models.Model):
    ARTICLE_ID = models.CharField(max_length=20, verbose_name="文章编码", primary_key=True)
    TITLE = models.CharField(max_length=40, verbose_name="文章主题")
    CONTENT = models.TextField(max_length=100000, verbose_name="文章内容")
    DATE = models.DateTimeField(verbose_name="发表文章时间")
    CATEGORY = models.CharField(max_length=20, verbose_name="文章类别")
    AUTHOR = models.CharField(max_length=20, verbose_name="文章作者")
    BROWSE = models.CharField(max_length=10, verbose_name="阅读量")
    def __str__(self):
        return self.TITLE
    class Meta:
        db_table = "ARTICLE"
        verbose_name = '文章'
        verbose_name_plural = verbose_name

 

模型的数据库操作方法(CRUD)

1.通过视图向DB中增加数据

​ 1.Entry.object.create(属性=值,属性=值)

​ ex:

​ Auther.object.create(

​ name="老舍",age="50",email="1223@qq.com"

)

​ 2.创建Models 类的对象,通过save()增加

​ obj = Entry(属性=值,属性=值)

​ obj .save()

​ 3.通过字典创建Models类的对象,save()增加

​ dic={

​ '属性':‘值’

​ }

​ obj = Entry(**dic)

​ obj .save()

2.通过视图查询数据

​ 所有的查询都要基于Entry.objects的基础上完成

​ 1.查询接口

​ 1.all()

​ 语法:entry.objects.all()

​ 返回:QuerySet - 查询结果

​ sql :select * from Entry

​ 2.values()

​ 语法:entry.objects.all().value()

​ 作用:Query Set

​ ex:

​ Author.objects.all().value('name','age')

​ 3.order_by()

​ 语法:Entry.objects.all().order_by('id')

​ 作用:对查询结果集中的数据进行排序

​ 返回:QuerySet

​ ex:

​ Author.objects.all().order_by('id')

​ 所有数据按照id列的值升序排序

​ Author.objects.all().order_by('-id')

​ 所有数据按照id列的值降序排序

​ 4.exclude()

​ 语法:Entry.objects.exclude(属性=值)

​ 作用:对指定条件取反

​ 返回:QuerySet

​ ex:

​ 1.Author.objects.exclude(id=3)

​ 2.Author.objects.exclude(id=3,age=50)

​ 5.filter()

​ 语法:Entry.objects.filter(条件)

​ 作用:将满足条件的数据筛选出来

​ 返回:QuerySet

​ 6.get()

​ 语法:Entry.objects.get(条件)

​ 返回:一个models对象

注意:该函数只能返回一个对象,返回多个或没有查询到数据的话都抛出异常

​ 2.查询谓词

​ 每个查询谓词都是一个条件,真正查询时会将谓词翻译成对应的条件语句

​ 常用查询谓词

​ 常用查询谓词:

​ 1.__exact

​ 作用:等值判断,等同于 =

​ Author.objects.get(id_exact = 1)

​ = Author.objects.get(id = 1)

​ 2.lt、gt、gte、lte(前置双下滑线)

​ 作用:数值比较

​ Author.objects.filter(age__gt = 35) = age > 35

​ 3.__contains

​ 作用:查询包含指令字符的

​ Author.objects.filter(name__contains='元')

​ select * from author where name like ‘%元%’

​ 4.startwith,endwith

​ 作用:查询指定字符作为开始/结束

​ Auhtor .objects.filter(name__startwith=’霍‘)

​ Author.objects.filter(name__endwith="真")

3.通过视图修改操作

1.修改单个对象

​ 1.通过get()得到要修改的models对象

​ 2.通过models对象直接修改数据即可

​ 3.通过models对象的save()函数直接保存

​ author = Author.objects.get(id=1)

​ auhtor.name = '爱新觉罗·康熙'

​ author.age = 200

​ author.save()

2.批量修改

​ 调用QuerySet的update()即可完成

​ Author.objects.all().update(属性=值,属性=值)

4.通过视图删除数据

​ 1.delete()

​ Author.objects.get(id=2).delete()

​ Author.objects.filter(age__gt=50).delete()

5.F()操作和Q()操作

​ 1.F()

​ update author ser age = age + 10

​ Author .objects.all().update(age = age+ 10)

​ 作用:用于执行过程中获取某列的值

​ 语法:F('列名')

​ from Django.db.models import F

​ Author .objects.all().update(age = F('age') + 10)

​ 2.Q()

​ from django.db.models import Q

​ Author.objects.filter(Q(id=1) | Q(age=60))

 

​ 6.原生的数据库操作

​ 1.查询

​ 接口:raw()

​ 语法:Entry.objects.raw(sql)

​ 参数sql:要执行的查询SQL语句

​ 2.增删改

​ def cud(request):

​ with connection.cursor() as cursor:

​ sql = '...'

​ cursor.execute(sql)

​ return render(......)

1.使用后台管理models

1.创建管理员

​ manage.py createsuperuser

​ username:admin 指定用户

​ email:1175715363@qq.com 指定邮箱

​ password:adminadmin 密码8位

2.基本管理

1.在应用中admin.py 中注册要管理的models

​ 1.admin.py

​ 作用:注册需要管理的models,只有在此注册的models才允许被后台管理

​ 2.注册Models

​ from .models import *

​ admin.site.register(Entry)

​ ex:

​ admin.site.register(Author)

​ 3.修改models.py 处理显示的内容

​ 在models 中的各个class中追加

​ def ——str--(self):

​ return self.name

​ 4.通过Meta内部类实现 展开属性

​ 每个models 类中都可以声明 内部类Meta

​ class Author(models,Models):

​ ...

​ class Meta:

​ 1.db_table:指定实体类对应的表的名字

​ 2.verbose_name:定义类在admin中显示的名称(单数形式)

​ 3.verbose_name_plural:效果同上,复数形式

​ 4.ordering:指定数据们的排序方式,取值为一个列表,默认是升序排序,降序

​ 的话加减号’-'

2.高级管理

1.在admin.py中创建管理类,实现高级管理功能

一般情况下需要在创建完models之后进行高级管理配置

​ 1.定义EntryAdmin,继承自admin.ModelsAdmin

​ class AuthorAdmin(admin.ModelsAdmin):

​ pass

​ 2.注册 高级管理类

​ admin.site.register(Entry,EntryAdmin)

​ admin.site.register(Author,AuthorAdmin)

2.允许在EntryAdmin中增加的属性

1.list_display()

​ 作用:指定显示在实体信息页上的字段

​ 取值:有属性名组成的元组或列表

​ ex:

​ list_display = [

​ 'name','age','email'

​ ]

2.list_display_links

​ 作用:定义能够链接到详细页面的链接

​ 取值:有属性名组成的元组或列表

​ 注意:取值必须出现在list_display中

3.list_editable

​ 作用:指定在是信息页上允许被修改的字段

​ 取值:由属性名组成的元组或列表

​ 注意:取值不能出现在list_display_links中的值

4.search_fields

​ 作用:添加允许被搜索的字段

取值:由属性组成的元组

  1. 过滤器list_filter

作用:在实体信息页右侧增加一个过滤器

一遍实现快速筛选

取值:由属性名组成的

6.date_hierarchy

​ 作用:在实体信息页面的顶部增加时间选择器

​ 取值:必须是DateField 或DateTimeField的列名

7.fields

​ 作用:在实体的详细页中,定义显示那些字段,按照什么样的顺序

​ 取值:由属性名组成的元组或列表

8.fieldsets

​ 作用:在实体详细页面中,对属性进行分组

​ 注意:fieldsets 和 fields不能同时出现

​ 语法:

​ fieldsets = (

​ ('分组名称1',{

​ 'fields':('字段1','字段2'),

​ 'classes':('collapse')}),

​ ('分组名称2',{

​ 'fields':('字段1','字段2'),

​ 'classes':('collapse')}),

)

举个栗子:

from django.contrib import admin
from .models import *

# Register your models here.
class ARTICLEAdmin(admin.ModelAdmin):
    list_display = ['ARTICLE_ID', 'TITLE', 'DATE', 'CATEGORY', 'AUTHOR','BROWSE']
    list_display_links = ['TITLE']
    list_editable = []
    list_filter = ['CATEGORY', 'AUTHOR']
    fieldsets = (
        ('基本信息:', {'fields': ('ARTICLE_ID', 'TITLE', 'CONTENT')}),
        ('高级信息设置:',
         {'fields': ('DATE', 'CATEGORY', 'AUTHOR','BROWSE'),
          'classes': ('collapse',)}),
    )

admin.site.register(ARTICLE, ARTICLEAdmin)

 

2.Django的连接查询(关系映射)

1.一对一映射(1:1)

1.什么是一对一

​ A表中的一条数据对应B表中的一条数据

​ 典型代表:一夫一妻

​ 数据库中的实现:

​ A表:设置主键

​ B表:增加一列,并引用自A表中的主键,并增加唯一约束

2.语法

​ 一对一涉及到两个类中的任何一个类

​ 属性 = models.OneToOneField(Entry)

​ class Author(models.Model):

​ name = models.CharField(max_length=30)

​ class Wife(models.Model):

​ name = models.CharField(max_length=30)

​ author = models.OneToOneField(Author,on_delete=models.CASCADE)

​ 正向查询:通过wife找Author

​ wife = Wife.objects.get(id=1)

​ author = wife.author

​ 反向查询:通过Author找wife

​ author = Author.objects.get(name='霍元甲')

​ wife = author.wife

2.一对多

1.什么是一对多

​ A表中的一条数据对应B表中的任意条数据

​ 如:出版社 和 书籍

​ 在数据库中的体现

​ A表:设置主键

​ B表:引用A表的主键

2.语法

​ 使用外键(Foreign Key)

​ 属性 = models.ForeignKey(Entry)

​ ex:

​ Book(m)和Publisher(1)

​ class Book():

​ publisher = models.ForeignKey(Publisher,null=True,on_delete=models.CASCADE)

3.查询

​ 1.正向查询 通过book找publisher

​ title = '通过book找publisher'

​ book = Book.objects.get(id=1)

​ publisher = book.publisher

​ 2.反向查询 通过publisher找book

​ publisher = Publisher.objects.get(name='交大出版社')

listbook= publisher.Book

3.多对多

1.什么是多对多

​ A表中一条数据对应B表中任意条数据匹配,

​ 同时B表中的一条数据也可以与A表中的任意条数据对应

2.语法

​ 在多对多的任何一个Models类中均可实现

​ entry = models.ManyToManyField(Entry)

​ class Book(models.Model):

​ ......

​ class Author(models.Model):

​ book = models.ManyToManyField(Book)

3.自定义查询对象(objects)

​ 1.声明类 EntryManager,继承自models,Manager,在EntryManager中增加自定义的函数

​ class AuthorManager(models.Model):

​ def 函数名(self,自定义参数):

​ ....

​ return ...

​ def .........

3.HttpRequest

1.什么是HTTPRequest

​ HttpRequest,请求对象,封装了请求对象过程中所有在Django中的数据,HttpRequest被化成了request封装到了视图处理函数中作为参数,该参数在试图处理函数被动调用时,自动传入。

2.HttpRequest中的主要内容

​ 1.request.scheme: 请求协议

​ 2.request.body: 请求主体

​ 3.request.path: 请求路径

​ 4.request.method: 请求方式

​ 5.request.get_host(): 请求主机地址或者域名

​ 6.request.GET: 封装了GET方式的请求数据

​ 7.request.POST: 封装了POST方式的请求数据

​ 8.request.COOKIES: 封装了cookies的数据

​ 9.request.META: 封装了请求的元数据

3.有关HTTP协议

1.每一个请求会有method

​ 请求的method默认为get

​ method:get、post、put、delete

​ get:请求数据在地址栏后

​ Query String

​ post:请求数据在请求主体中

​ FormData

2.请求主体

​ 只有post、put才能产生请求主体

4.csrf 跨站点攻击

​ 目的:解决跨站点发送POST请求的问题

​ 解决方案:

​ 1.删除Django.middleware.csrf.CsrfViewMiddleware

​ 2.在处理的视图上加上标记@csrf_protect

​ 3.在模板中

的底下第一行增加一个

​ {%scrf_token%}

5.获取请求提交数据

1.GET请求

​ request.GET['名称']

2.POST请求

​ request.POST['名称']

​ 建议:request.POST.get('名称')

​ request.POST.get(name)