目录
一、Django 简介
Django 是一个由 Python 写成的开放源代码的 Web 应用框架。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统)软件。并于2005年7月在 BSD 许可证下发布。这套框架是以比利时的吉普赛爵士吉他手 Django Reinhardt 来命名的。由于 Django 的是在一个快节奏的新闻编辑室环境下开发的,它的目的是使常见的 Web 开发任务,快速和容易。
特点
MTV 模式
Django 采用了 MTV 设计模式
上述图大概是说:
- URL ( urls.py )请求调度,当有缓存页面的时候直接返回内容。
- 视图函数( view.py )执行所请求的操作,通常包括读写数据库。
- 模型( models.py )定义了 Python 中的数据并与之交互。通常包含在一个关系数据库( MySQL、PostgreSQL SQLite 等),其他数据存储是可能的( XML、文本文件、LDAP、等)。
- 请求执行任务后,视图返回一个 HTTP 响应对象(通常是经过数据处理的一个模板)。可选的:视图可以保存一个版本的 HTTP 响应对象,返回携带一个时间戳,来告诉浏览器这个视图的更新时间。
- 模板通常返回 HTML 页面。Django 模板语言提供了 HTML 的语法及逻辑。
二、安装Django
# pip 安装
pip install Django
# 克隆下载最新版本
git clone https://github.com/django/django.git
# 导入django模块
>>> import django
>>> print(django.get_version())
三、基本配置
1、常用命令
# 查看django版本
$ python -m django --version
# 创建项目,名为mysite
$ django-admin startproject mysite
# Django项目环境终端
$ python manage.py shell
# 创建应用程序,确保和 manage.py 是同一目录
$ python manage.py startapp polls
# 启动django
$ python manage.py runserver
$ python manage.py runserver 8080
$ python manage.py runserver 0.0.0.0:8000
# 运行创造模型变化迁移
$ python manage.py makemigrations
# 运行应用模型变化到数据库
$ python manage.py migrate
# 同步数据库
$ python manage.py syncdb
# 清空数据库(保留空表)
$ python manage.py flush
# admin创建管理员用户
$ python manage.py createsuperuser
# 修改用户密码
$ python manage.py changepassword username
注:自动重新加载 runserver,根据需要开发服务器自动重新加载Python代码为每个请求。您不需要重新启动服务器代码更改生效。然而,像添加文件某些操作不触发重新启动,所以你必须重新启动在这些情况下的服务器。
基本目录结构及作用:
mysite/ # 项目的容器,名字随便起
manage.py # 命令行实用工具,以各种方式与该Django项目进行交互
mysite/ # 实际的Python项目
__init__.py # 空文件,导入不出错
settings.py # 这个Django项目配置
urls.py # 这个Django项目的URL声明; 一个Django驱动网站的“目录”
wsgi.py # 一个入口点为WSGI兼容的Web服务器,以满足您的项目
2、配置文件
INSTALLED_APPS = [
'django.contrib.admin', # 管理站点。
'django.contrib.auth', # 认证系统
'django.contrib.contenttypes',# 用于内容类型的框架
'django.contrib.sessions', # 会话框架
'django.contrib.messages', # 消息框架
'django.contrib.staticfiles', # 管理静态文件的框架
'blog.apps.BlogConfig', #是创建应用app的名字,如果项目创建了app则必须要添加app的名字
]
2.1、数据库
# django支持sqlite,mysql, oracle,postgresql数据库
# django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
# 设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb()
# 在settings 中修改DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname', # 数据库名称
'USER': 'root', # 用户名
'PASSWORD': 'xxx', # 密码
'HOST': '', # IP,留空默认localhost
'PORT': '', # 端口
}
}
2.2、模板
# 在settings里修改,放html文件
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)
2.3、静态文件
# 在settings里修改添加,放css,js,image等文件
# 创建static文件夹
STATIC_URL = '/static/' # 相当于别名
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
# 如引用Jquery文件,有俩种形式
1、 直接引入
2、 {% load staticfiles %}
{% static '文件名' %}
# 推荐使用第二种形式,第一条代码并处理引入文件代码的上方
# 再每个app里面我们可能会有多个文件配置信息,则可以相应的将文件夹放在app的文件夹下,并修改路径。
复制代码
2.4、引入静态文件的注意点
# 注意1:
# 为了后端的更改不会影响前端的引入,避免造成前端大量修改
STATIC_URL = '/static/' # 引用名
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"), # 实际名 ,即实际文件夹的名字
)
# django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找
# <script src="/statics/jquery-3.3.1.js"></script>
# ------error-----不能直接用,必须用STATIC_URL = '/static/':
# <script src="/static/jquery-3.3.1.js"></script>
# 注意2(statics文件夹写在不同的app下,静态文件的调用):
STATIC_URL = '/static/'
STATICFILES_DIRS=(
('hello',os.path.join(BASE_DIR,"app01","statics")),
)
# <script src="/static/hello/jquery-3.3.1.min.js"></script>
# 注意3:
STATIC_URL = '/static/'
{% load staticfiles %}
# <script src={% static "jquery-3.3.1.min.js" %}></script>
# 注意4:
配置STATIC路径时,记得要最后一个元组后面加逗号,不然会影响渲染
四、路由系统
1、URL 调度
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。
django最新版url默认不支持正则,标准格式:
path('admin/', admin.site.urls),
如果需要使用正则,需要导入:re_path,使用方法:
from django.urls import path,re_path
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^test-(\d+)-(\d+)/', views.test),
path('index/', views.index),
]
来看以下示例,如何动态构造:
urlpatterns = [
path('admin/', admin.site.urls),
path('show_time/', views.show_time), #无名分组
re_path(r'article/(\d{4})$', views.article_year), #有名分组:(?p<分组名>正则语法)
]
# 参数说明
# 一个正则表达式字符串
# 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
# 可选的要传递给视图函数的默认参数(字典形式)
# 一个可选的name参数
需要注意: url多传了一个参数,那views函数得多接受一个参数
def show_time(requset):
# return HttpResponse("Hello")
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
# 对应接收值
def article_year(request,y):
return HttpResponse(y)
对应该的index.html
<h1>time:{{ t }}</h1>
2、name别名
name就是该views函数的别名
name别名要结合模板文件来用方便管理
urls.py
urlpatterns = [
path("register",views.register,name="reg"),
]
在html文件中引入
<form action="{% url 'reg' %}" method="post">
3、路由分发(include)
如果一个项目下有很多的app,那么在urls.py里面就要写巨多的urls映射关系。这样看起来很不灵活,而且杂乱无章。这时候就要根据不同的app来分发不同的url请求
首先,在urls.py里写入urls映射条目。注意要导入include方法
from django.contrib import admin
from django.urls import path, re_path, include
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^blog/', include('blog.urls')),
]
这条关系的意思是将url为”blog/“的请求都交给blog下的urls去处理
其次,在blog下创建一个urls.py文件,用来处理请求的url,使之与views建立映射
from django.urls import path, re_path, include
from blog import views
urlpatterns = [
re_path(r'article/(\d{4})$',views.article_year),
re_path(r'article/(?P<year>\d{4})/(?P<month>\d{2})',views.article_year_month),
re_path(r'article/(?P<year>\d{4})/(?P<month>\d{2})/\d+',views.article_year_month),
re_path(r"register",views.register,name="reg"),
1、STATIC_ROOT:在settings里面设置,一般用来放一些公共的js,css,images等。
2、app的static文件夹,在每个app所在文夹均可以建立一个static文件夹,然后当运行collectstatic时,
python manage.py collectstatic
Django会遍历INSTALL_APPS里面所有app的static文件夹,将里面所有的文件复制到STATIC_ROOT。因此,如果你要建立可复用的app,那么你要将该app所需要的静态文件放在static文件夹中。
也就是说一个项目引用了很多app,那么这个项目所需要的css,images等静态文件是分散在各个app的static文件
比较典型的是admin应用。当你要发布时,需要将这些分散的static文件收集到一个地方就是STATIC_ROOT。
3、STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。
STATIC_URL的含义与MEDIA_URL类似。
部分源码
五、视图层
1、概述
client端通过http请求——去url的路由找到相应的视图函数——触发视图函数——再去modes取数据——取到数据后——再通过创建模——views函数把相响应对象——返回给client最终显示的内容
视图文件(views.py)在app目录下才有
看看新建项目默认的views.py文件的内容
from django.shortcuts import render, HttpResponse
import time
# Create your views here.
通过相应的url请求来写不同请求的视图函数
2、视图函数的编写
def show_time(requset):
# return HttpResponse("Hello")
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
视图要结和url路由,models,模板文件一起来用。
3、视图函数的参数
第一个参数
视图函数的参数必须是url的请求对象一般写为request
后面及其他的参数
是url路由的分组信息,一个参数表示一个分组,两个参数表示两个分组
def article_year(request,y):
return HttpResponse(y)
def article_year_month(request,year,month):
return HttpResponse("year:%s month:%s"%(year,month))
4、请求和响应对象
Django 使用请求和响应对象在系统间传递状态。
当请求一个页面时,Django 创建一个 HttpRequest
对象包含原数据的请求。然后 Django 加载适当的视图,通过 HttpRequest
作为视图函数的第一个参数。每个视图负责返回一个HttpResponse
目标。
A、HttpRequest对象
HttpRequest.scheme
一个字符串表示请求的方案(HTTP或HTTPS)通常
HttpRequest.path
一个字符串的完整路径的请求
HttpRequest.method
请求的HTTP方法。这是保证要大写
if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()
HttpRequest.GET
字典像包含所有给定的HTTP GET参数对象。
HttpRequest.POST
字典像包含所有给定的HTTP POST参数对象,提供请求包含表单数据。
HttpRequest.COOKIES
一个标准的Python字典,包含了所有的COOKIES,key和values都是字符串
HttpRequest.FILES
字典像对象包含所有上传的文件。
html 标签 <input type="file" name="" />
filename # 上传的文件名
content_type # 上传文件的类型
content # 上传文件的内容
HttpRequest.META
一个标准的Python字典包含所有可用的HTTP头。可用标题取决于客户端和服务器,但这里是一些例子:
CONTENT_LENGTH – 请求体的长度(一个字符串)。
CONTENT_TYPE – 请求体的类型。
HTTP_ACCEPT - 为响应–可以接受的内容类型。
HTTP_ACCEPT_ENCODING – 接受编码的响应
HTTP_ACCEPT_LANGUAGE – 接受语言的反应
HTTP_HOST – 客户端发送的HTTP主机头。
HTTP_REFERER – 参考页面
HTTP_USER_AGENT – 客户端的用户代理字符串。
QUERY_STRING – 查询字符串,作为一个单一的(分析的)字符串。
REMOTE_ADDR – 客户端的IP地址
REMOTE_HOST – 客户端的主机名
REMOTE_USER – 用户通过Web服务器的身份验证。
REQUEST_METHOD – 字符串,如"GET"或"POST"
SERVER_NAME – 服务器的主机名
SERVER_PORT – 服务器的端口(一个字符串)。
B、HttpResponse对象
对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。
在HttpResponse对象上扩展的常用方法:
5、render()
render(request, template_name, context=None, content_type=None, status=None, using=None)[source]
结合给定的模板与一个给定的上下文,返回一个字典HttpResponse在渲染文本对象
template_name 一个模板的使用或模板序列名称全称。如果序列是给定的,存在于第一个模板将被使用。
可选参数
- context 一组字典的值添加到模板中。默认情况下,这是一个空的字典。
- content_type MIME类型用于生成文档。
- status 为响应状态代码。默认值为
200
- using 这个名字一个模板引擎的使用将模板。
def show_time(requset):
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
6、render_to_response()
render_to_response(template_name, context=None, content_type=None, status=None, using=None)[source]
这个和 render() 差不多,它不需要传入request对象,并不推荐使用
7、redirect()
redirect(to, permanent=False, *args, **kwargs)[source]
此方法可称之为页面跳转,可以得到达到某种条件时,如再登陆淘宝界面,登陆成功之后会跳转到用户的主界面
默认情况下,为临时重定向;通过 permanent=True
设置永久重定向
from django.shortcuts import render, HttpResponse,redirect
def register(request_info):
if request_info.method == 'POST':
user = request_info.POST.get('user')
pwd = request_info.POST.get('pwd')
if user == 'Aaron' and pwd == '123456':
return redirect("/login/") #直接跳转,url已经发生了变化
# return render(request,"login.html",locals())#url还是register,当你刷新 时又回到原来的了
return HttpResponse('账号或密码错误')
return render(request_info,'register.html')
def login(request_info):
return render(request_info,'login.html')
# 在此可能会想到用render也可以再条件达成之后进行页面的跳转。
# 那么俩者之间有什么区别呢
# 1、the most important: url没有跳转到/login/,而是还在/register/,所以当刷新后又得重新登录.
# locals()
它是局部的,渲染所有的局部变量,可以将函数内所有的变量传递request对象获取到。
注意点、此时视图函数内的变量名称要和前端代码的变量名称对应
def student(req):
student_list=["小明","小红","老五","明明"]
return render(req,"student2.html",locals())
#student2.html
{% for student in student_list %}
<h2>学生{{ student }}</h2>
{% endfor %}
总结:
render() #页面渲染,推荐 (很少用HttpResponse)
redirect("路径") 例如登录跳转
locals(): 可以直接将函数中所有的变量传给模板
完整示例源码