- Django简介
- python下有多款不同的web框架,Django是最有代表行的一种。许多成功的网站和app都基于djanfo。
- django是一个开源的web应用框架,由python写成。
- django采用了MVC的软件设计模式,即模型M,视图V和控制器C。
- Django特点
- 强大的数据库功能:用python的类继承,几行代码就可以拥有一个动态的数据库操作API,如果需要也能执行SQL语句。
- 自带的强大的后台功能:几行代码就让网站拥有一个强大的后台,轻松管理内容。
- 优雅的网址:用正则匹配网址,传递到对应函数。
- 模板系统:强大,易扩展的模板系统,设计简易,代码和样式分开设计,更易管理。
- 缓存系统:与memcached或其它缓存系统联用,表现更出色,加载速度更快。
- 国际化:完全支持多语言应用,允许你定义翻译的字符,轻松翻译成不同国家的语言。
- Django项目目录
manage.py:用来管理当前项目的一个命令行工具
myproject/: 项目主文件夹
myproject/__init__.py:空文件,用来指明当前的myproject为一个可导入的模块包
myproject/settings.py:项目主要配置文件
myproject/urls.py:项目主要路由配置文件
myproject/wsgi.py:项目部署WSGI并发服务器时所需要的配置
-
安装Django
- pip install django 默认安装最新版本
- pip install django==2.0.4 (指定版本号安装)
-
- 创建项目
- django-admin startproject mypro
-
- 开启开发服务器
- cd myproject 进入项目目录
- python manage.py runserver 开启服务
- python manage.py runserver 7000 改变服务监听端口
- python manage.py runserver 0:8000 改变服务监听IP:端口
-
- 配置settings.py
- BASE_DIR : 当前项目工作目录,用来在每一次开启项目时动态找到相关资源路径
- SECRET_KEY : 加密的hash值以及保护某些签名数据的关键密钥
- DEBUG : 调试模式
- ALLOWED_HOSTS : 有哪些主机或域名可以访问当前django站点,如设置为*代表全部可访问。
- INSTALL_APPS : django项目中所有使用的应用名称,自创建子应用也要加到这里,不然ORM数据库无法被识别到!
- MIDDLEWARE : django中间件,用来在request或reponse过程中添加功能,比如确保安全性,传输保存Session等
- SecurityMiddleware : xss脚本过滤,一些安全设置
- SessionMiddleware : session支持中间件,在每次用户访问django项目时,添加session对每一个浏览器
- CommonMiddleware : 通用组件,比如为路由添加末尾斜杠
- CsrfViewMiddleware : 防跨站请求伪造令牌,为客户端添加csrf_token密钥,在表单提交时需提交该值
- AuthenticationMiddleware : admin用户组件,每个request对象都会被添加admin下的user属性
- MessageMiddleware : 消息中间件 展示一些后台消息给前端
- XFrameOptionsMiddleware : 防止欺骗点击攻击出现;自身页面被嵌入到他人页面中,点击欺骗
- ROOT_URLCONF : 主路由配置文件,字符串填写url.py文件路径
- TEMPLATES : 模板文件配置项
- WSGI_APPLICATION : WSGI服务器配置项,找到当前django下的wsgi引入APP文件
- DATABASES : 数据库配置项,默认使用SQLite3,一个本地文件数据库
- AUTH_PASSWORD_VALIDATORS : 检查用户密码强度的验证程序列表,不过是针对admin界面下的用户,而非自定义
- LANGUAGE_CODE : django所使用语言文件
- TIME_ZONE : django所使用时区
- USE_I18N : 国际化支持 18表示Internationalization这个单词首字母I和结尾字母N之间的字母有18个
- USE_L10N : 是localization的缩写形式,意即在l和n之间有10个字母
- USE_TZ :开启了Time Zone功能,则所有的存储和内部处理,包括print显示的时间将是是UTC时间格式
- STATIC_URL : URL访问静态资源时的路径
-
- 创建子应用
- 项目和应用有啥区别?
-
- 创建app
- cd mypro
- django-admin startapp helloapp
-
- 页面和视图
- 视图函数
1 # 每一个视图函数都需要有一个必须参数 request,用来接收用户访问时的请求内容 2 from django.http import HttpResponse 3 def index(request): 4 return HttpResponse("<h1>Hello world</h1>
HttpResponse函数用来像用户返回一个字符串。
- 路由配置
-
- 第一种简单的路由配置,直接在主控路由文件下,找到这个视图函数
1 #myproject/urls.py 2 from django.contrib import admin 3 from django.urls import path 4 from myapp import views 5 urlpatterns = [ 6 path('admin/', admin.site.urls), #admin控制界面路由 7 path('',views.index) 8 #path函数第一个参数为访问地址,空字符串代表:当用户直接访问首页时 9 #第二个参数代表访问该地址时对应的视图函数,我们引入了app下的views中的index视图函数。 10 ]
接下来访问127.0.0.1:8000,那么你会看到一个非常大的Hello world。
-
- 以上将视图函数的查找直接写到主控路由并不是最好的办法,我们的项目通常会有非常多的路由配置项,如果都堆到这个文件中肯定是非常乱的,难以维护;我们可以在对应app下创建一个子路由控制文件,并在其中设置视图的路由配置。
1 #myapp/urls.py 2 from django.urls import path 3 from . import views 4 urlpatterns = [ 5 path("",views.index) 6 ]
-
- 现在虽然配置了app下的路由文件,但是访问时,是看不到对应视图的结果这是因为默认的url查找动作将会从主控路由文件开始,我们还需要在主控路由文件下进行路由分发设置,让主控路由可以找到子app下的路由
1 #myproject/urls.py 2 from django.contrib import admin 3 from django.urls import path,include 4 from myapp import views 5 urlpatterns = [ 6 path('admin/',admin.site.urls), 7 #path('',views.index) 8 path('',include("myapp.urls")), 9 # 函数 include() 允许引用其它 URLconfs 10 ]
接下来再次尝试,在浏览器中访问主机域名;如果可以看到的话,恭喜你,效果已经很棒了!
路由查找流程:
1. 查找主控路由文件下的 urlpatterns 全局变量,这是一个序列数据类型,其中每一个元素都是对应的一个路由匹配规则
2. 如果在规则中查找到符合匹配规则的,则执行其中的对应执行函数
3. 如果对应的不是一个执行函数,而是一个 include 路由包含,那么截断与此项匹配的 URL 的部分,并将剩余的路由字符串发送到 include所包含的子路由文件中以供进一步处理4. 如果没有匹配到的任何结果,django默认抛出 Page not found (404)
注意:Django的路由不考虑HTTP请求方式,仅根据URL进行路由,即,只要URL相同,无论POST、GET等哪种请求方式都指向同一个操作函数。
- path
1 path(route, view, name) 2 #route: 匹配规则,是一个字符串 3 #view:对应的视图函数 4 #name:未来我们会用到他,用来为匹配规则命名,这样方便日后修改路由而不影响全局下的路由使用
- re_path
- 模板页面
返回一个字符串这肯定是不行的,太low了,也不好看,现在来返回一个正式的HTML页面。并在HTML页面中加入模板变量,由视图函数动态传递值;配置django中模板页面的保存路径,在项目目录下的settings.py文件中。
1 #myproject/settings.py 2 TEMPLATES = [ 3 { 4 'BACKEND': 'django.template.backends.django.DjangoTemplates', 5 'DIRS': [os.path.join(BASE_DIR,'template')], # 就是这一行设置静态模板路径 6 'APP_DIRS': True, 7 'OPTIONS': { 8 'context_processors': [ 9 'django.template.context_processors.debug', 10 'django.template.context_processors.request', 11 'django.contrib.auth.context_processors.auth', 12 'django.contrib.messages.context_processors.messages' 13 ], 14 }, 15 }, 16 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>hi</title> 6 </head> 7 <body> 8 <h1>{{ message }}</h1> 9 </body> 10 </html>
在HTML页面中,我们并没有明确指出H1标签的内容;通过一个{{ message }}来等待接收视图函数传来的数据,在HTML页面中这样的变量也叫做模板变量,常用双大括号语法。
接下来修改之前的视图函数,由视图函数传递变量给到HTML页面。
1 #myapp/views.py 2 from django.shortcuts import render 3 def index(request): 4 #return HttpResponse("<h1>Hello world</h1>") 5 content = {"message":"你好,世界" #此处的key值message对应页面中我们写的{{ message }} 6 } 7 return render(request,'index.html',content)
- 为什么模板文件夹中还要在创建一个hello子文件夹呢?
- 页面中使用URL
1 <a href="{% url 'hello' '张三' %}">你好,张三</a>
1 path('hello/<str:name>', views.hello, name='hello')
1 app_name = 'hello' urlpatterns = [ path('', views.index, name='index'), path('hello/<str:name>', views.hello, name='hello') ]
1 <a href="{% url 'hello:hello' '张三' %}">你好,张三</a>
- 静态文件
虽然有了模板页面,可以来展示一些标签的效果,但是整个HTML还是感觉很丑陋,所以,我们还要继续引入
一些类似css、img这样的静态资源,来装饰我们的页面。
在django中模板页面的静态资源使用,不能像之前写HTML代码直接引入,需要我们首先在项目中创建目录保
存对应的静态资源。
-
- 在settings中配置静态文件保存目录,添加如下内容:
有些静态文件可能是多个app公用的,这时候需要进行一点额外设置。首先在和app同级的目录创建static文件夹并将静态文件放入。然后在配置文件中添加额外的搜索路径配置。
还是由于django文件搜索机制,我们最好在静态目录中添加一个public子文件夹和其他静态文件区分。
1 STATICFILES_DIRS = ( 2 os.path.join(BASE_DIR, 'static'), 3 ) 4 # STATICFILES_DIRS 该配置项用来告诉django在查找静态资源时,应该访问哪个目录
- 在项目中创建static目录,static目录下创建专门保存图片的img目录,在里面存一张图片1.jpg
-
- 有了图片,接下来在模板页面中去引入并使用它,打开index.html进行修改:
1 <!DOCTYPE html> 2 <html lang="en"> 3 {% load staticfiles %} 4 <head> 5 <meta charset="UTF-8"> 6 <title>hi</title> 7 </head> 8 <body> 9 <h1>{{ message }}</h1> 10 <img src='{% static "img/1.jpg" %}' alt="图片"> 11 </body> 12 </html>
-
- 这里用到了一个特殊语法: {% tag %} 这个叫静态标签,静态标签不同于模板变量,静态标签经常用来加载数据,或创建逻辑,比如之后我们要学到的 {% if %} ,使用静态标签可以方便我们在模板页面上实现某些只有在后台代码中才可以实现的逻辑功能。
- 在页面中要引入静态资源,图片,CSS,JS文件,在引入时都需要通过 {% static "path" %} 来进行引入,并且在模板页面头部需要使用 {% load staticfiles %} 标签进行静态资源的加载。
- 模型数据库
- 创建数据库,这里使用项目自带的SQLite3数据库,默认已经是配好的,接下来需要我们进入到app下的models.py文件中,编写一个类,这个类就对应数据库中的一张表。
-
1 #myapp/models.py 2 from django.db import models 3 # Create your models here. 4 class Weather(models.Model): 5 weather = models.CharField(max_length=100,verbose_name="天气") 6 class Meta:verbose_name_plural = "天气" 7 # 设置当前表名的一个可读的性更好的名字 8 def __str__(self): 9 return self.weather
-
- 在这里我们使用到了django的orm映射关系用来创建数据库表,继承自django的models.Model类,一个类用来表示一张表,类中的一个属性代表一个字段,这里我们定义了一个类型为CharField,长度为100的字段,用来存储天气。
-
- 下面的class Meta是模型类的元类,用来设置当前表的一些属性;这里我们使用verbose_name_plural属性设置当前表在admin后台查看时的名字
-
- 在这里我们还定义了一个属于实例的函数__str__,用来描述当前数据在返回时的默认展示结果,为weather字段的值
-
- django在创建模型类对应的数据表时,默认使用 应用名 加 下划线 加 模型类名 作为表的名字;比如当前Weather表名为:myapp_Weather
- orm映射关系,是django与数据库之间的一个桥梁,可以使开发者不再关注如何去编写SQL语句,直接通过一套ORM所提供的API接口即可方便对各种数据库进行交互。
-
- 当某个子应用APP涉及到了数据库的使用时,要记得在settings文件中进行配置:
1 #myproject/settings.py 2 INSTALLED_APPS = [ 3 'django.contrib.admin', 4 'django.contrib.auth', 5 'django.contrib.contenttypes', 6 'django.contrib.sessions', 7 'django.contrib.messages', 8 'django.contrib.staticfiles', 9 'myapp', 10 ]
- 接下来通过manage.py命令行管理工具提供的两条,创建我们所需要的数据。
-
-
- 注意:默认django本身就已经需要一些数据的创建,所以我们在初次执行以下两条命令时可能会看到很多数据表和字段的创建,不要惊讶,这是正常的
1 python manage.py migrate # 根据数据库迁移文件生成对应SQL语句并执行 2 # 初次执行是为了先把默认django需要的数据库创建出来 3 python manage.py makemigrations # 创建数据库迁移文件 4 # 这次执行是为了创建APP中Weather模型类的迁移文件 5 python manage.py # 将新添加的模型类迁移文件生成对应SQL并执行,实际创建出对应的Weathe表
-
Django Admin
-
- admin控制台是django为我们提供的一个非常便捷的用来管理数据库的界面。在主控路由文件下,其实你已经看到了它对应的路由设置:path('admin/', admin.site.urls),
- 进入admin界面,初次访问连接:127.0.0.1/admin,会提示我们输入账号密码,这是因为django的admin界面是需要一个超级管理员来登陆访问的,所以还需要我们创建对应的admin界面下的超级用户
- 创建admin超级用户,使用manage.py命令行执行如下命令:
-
python manage.py createsuperuser
Username (leave blank to use 'lienze'): root Email address: Password:Password (again): This password is too short. It must contain at least 8 characters. This password is too common. This password is entirely numeric. Password: Password (again): This password is too common. This password is entirely numeric. Password: Password (again): Superuser created successfully.
- 以上是我们创建超级用户的过程,非常坎坷;可以看到,在输入太短(不满足8位),或是只包含数字的简单密码,超级用户的创建都是被拒绝的所以我们把用户账号创建为 root ,而密码创建为 a1234567 ,接下来开启测试服务器,并通过创建好的超级用户登陆访问,如果幸运的话,你已经可以看到后台的admin界面啦admin界面已经展示出了默认django所使用的两张表,用户表和组表,用来保存当前管理后台的用户以及对应权限分组,可以点入用户表查看其中我们刚创建的root。
-
启动开发服务器
$ python manage.py runserver
-
进入管理站点页面
- admin注册表
- 在app下的admin.py文件中进行模型类的注册:
-
1 #myapp/admin.py 2 from django.contrib import admin 3 from myapp import models 4 admin.site.register(models.Weather) 5 #使用register函数接收模型类作为参数即可完成
- 例:
-
- 这个表单是从问题 Question 模型中自动生成的
- 不同的字段类型(日期时间字段 DateTimeField 、字符字段 CharField)会生成对应的 HTML 输入控件。每个类型的字段都知道它们该如何在管理页面里显示自己。
- 每个日期时间字段 DateTimeField 都有 JavaScript 写的快捷按钮。日期有转到今天(Today)的快捷按钮和一个弹出式日历界面。时间有设为现在(Now)的快捷按钮和一个列出常用时间的方便的弹出式列表。
- 保存(Save) - 保存改变,然后返回对象列表。
- 保存并继续编辑(Save and continue editing) - 保存改变,然后重新载入当前对象的修改界面。
- 保存并新增(Save and add another) - 保存改变,然后添加一个新的空对象并载入修改界面。
- 删除(Delete) - 显示一个确认删除页面。
- 视图操作模型
1 #myapp/views.py 2 from django.shortcuts import render 3 from myapp import models 4 def index(request): 5 weathers = models.Weather.objects.all() 6 content = { 7 "weathers":weathers, 8 } 9 return render(request, 'index.html', content)
1 <!DOCTYPE html> 2 <html lang="en"> 3 {% load staticfiles %} 4 <head> 5 <meta charset="UTF-8"> 6 <title>hi</title> 7 </head> 8 <body> 9 {% for weather in weathers %} 10 <p>{{ weather }}</p> 11 {% empty %} 12 <p>没有任何天气</p> 13 {% endfor %} 14 </body> 15 </html>