目录
一、第一个Django项目
?Django的优点和缺点
第一个表BookInfo类
第二个表HeroInfo类
数据库操作
后台管理
视图
?模板的使用
?连接数据库
二、Django配置信息
(一)资源文件配置
资源文件配置
静态资源文件
媒体资源文件
(二)templates模板配置
(三)数据库配置
1、mysqlclient连接mysql
2、pymysql连接MySQL
3、多个数据库的连接方式
4、使用配置文件动态连接数据库
5、通过SSH隧道远程连接MySQL
(四)路由
路由(一)路由配置
1、创建项目
2、settings.py文件中,注册index
?3、新建一个文件夹templates,新建一个index.html,并在settings.py文件的TEMPLATES添加DIRS
5、运行python manage.py runserver
?路由(二)路由变量、正则路由定义、命名空间和路由命名
1、设置路由变量
2、正则表达式路由定义
3、命名空间和路由命名
路由(三)路由的使用方式
在模板中使用路由
反向解析reverse与resolve
路由重定向
1、在模板中使用路由
2、反向解析reverse与resolve
3、路由重定向
一、第一个Django项目
?Django的优点和缺点
优点
Python 实现,代码干净、整洁
提供管理后台,能够快速开发
复用度高,设计、使用上遵循DRY原则
易于扩展复用的中间件
内置的安全框架
丰富的第三方类库
缺点
单体应用-不易并行开发,单点扩展
不适合非常小的几行代码的项目
不适合于高并发的to C互联网项目
Django的设计思想
DRY (Don't repeat yourself) :不重复造轮子 MVT 快速开发 灵活易于扩展 松耦合 显式优于隐式
?安装
?anaconda下载
https://www.anaconda.com/products/individual
Python科学计算工具包:数据科学家的工具箱 包含了Python二进制发行包 包含Numpy, Pandas,Matplotlib, SciPy, Bokeh, Jupyter,PyTorch, Tensorflow等科学处理工具 包含了一个开源的Python IDE: Spyder 包含了Conda包管理软件: conda install xxx
使用conda命令安装Django
conda install django
pycharm下载
https://www.jetbrains.com/pycharm/download/#section=windows
pycharm安装Django
File——setting——Project
?
创建Django项目
django-admin startproject MyDjango
cd MyDjango
python manage.py startapp index #创建应用:index
?
可以使用cmd的tree命令查看目录树
tree /f?
?
views.py: ,接收请求,进行处理,与M和T进行交互,返回应答。定义处理函数,视图函数
tests.py:写测试代码的文件,用于实现单元测试。
admin.py:网站后台管理相关的文件。建立应用和项目之间的联系,需要对应用进行注册,修改settings.py中的INSTALLED_APPS配置项
_init.py:说明目录是一个Python模块
models.py:写和数据库项目的内容,每个类可以关联一张数据表
?
?运行开发web服务器命令
python manage.py runserver 8002
?
?
?没有设置端口就默认端口为8000
?
??注:没有ico图标,所以在日志中报错404,没影响
models.py——设计和表对应的类,模型类
?
模型类
模型设计类
在models.py中设计模型类
必须继承与models.Model类
1)设计BookInfo类
2)设计HeroInfo类
Models.ForeignKey可以建立两个模型类之间一对多的关系,django在生成表的时候,就会在多的表中创建一列作为外键,建立两个表之间一对多的关系。
diango.中内嵌了ORM框架,ORM框架可以将类和数据表进行对应起来,只需要通过类和对象就可以对数据表进行操作。
设计类︰模型类。
ORM另外一个作用︰根据设计的类生成数据库中的表。
第一个表BookInfo类
from django.db import models
class BookInfo(models.Model):
btitle=models.CharField(max_length=20)
bpub_date=models.DateField()
1)生成迁移文件
命令: python manage.py makemigrations?迁移文件是根据模型类生成的。
?
?
2)执行迁移生成表
命令: python manage.py migrate?根据迁移文件生成表.
生成表名的默认格式:
应用名_模型类名小写
?
?
?
?
第二个表HeroInfo类
# 关系属性对应的表的字段名格式:关系属性名_id(外键)
from django.db import models
# Create your models here.
#一类
#图书类
class BookInfo(models.Model):#继承于models模块里的Model类
#图书模型类
#类属性对应表里的字段
#图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle=models.CharField(max_length=20)
#出版日期,DateField说明是一个日期模型
bpub_date=models.DateField()
#多类
#人物类
class HeroInfo(models.Model):
hname=models.CharField(max_length=20)#名
hgender=models.BooleanField(default=False)#性别,BooleanField说明是bool类型,default指定默认值,False代表男
#备注
hcomment=models.CharField(max_length=128)
# 关系属性,建立图书和物一对多关系
# 关系属性对应的表的字段名格式:关系属性名_id(外键)
hbook=models.ForeignKey(to="BookInfo",on_delete=models.CASCADE)
?
?
?如果报错TypeError: __init__() missing 1 required positional argument: 'on_delete'
?问题出在models.py,应写上:
hbook=models.ForeignKey(to="BookInfo",on_delete=models.CASCADE)
?python manage.py migrate
?
?
数据库操作
?
?
表1
?
增删查改语句:
插入语句
?
?
查询语句
?
更新语句
?
?
删除语句
?
后台管理
1)本地化
语言和时区的本地化
修改settings.py
?
2)创建管理员
python manage.py createsuperuser
?
?打开浏览器,输入网址http://127.0.0.1:8000/admin
?
?
?
?
?
3)注册模型类
在应用下的admin.py中注册模型类
告诉django框架根据注册的模型类来生成对应表管理页面
b=BookInfo()
?str(b)_str_
from django.contrib import admin
from index.models import BookInfo
# 后台管理相关文件
# Register your models here.
#注册模型类
admin.site.register(BookInfo)
?
?
?
?
显示图书标题
?
查看str返回值
?
改变str返回值
models.py里重写方法
class BookInfo(models.Model):#继承于models模块里的Model类
#图书模型类
#类属性对应表里的字段
#图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle=models.CharField(max_length=20)
#出版日期,DateField说明是一个日期模型
bpub_date=models.DateField()
def __str__(self):
# 返回书名
return self.btitle
右侧可增加BOOK INFO
?
同理,增加第二个表Hero infos类
admin.py
from django.contrib import admin
from index.models import BookInfo,HeroInfo
# 后台管理相关文件
# Register your models here.
#注册模型类
admin.site.register(BookInfo)
admin.site.register(HeroInfo)
models.py
from django.db import models
# Create your models here.
#一类
#图书类
class BookInfo(models.Model):#继承于models模块里的Model类
#图书模型类
#类属性对应表里的字段
#图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle=models.CharField(max_length=20)
#出版日期,DateField说明是一个日期模型
bpub_date=models.DateField()
def __str__(self):
# 返回书名
return self.btitle
#多类
#人物类
class HeroInfo(models.Model):
hname=models.CharField(max_length=20)#名
hgender=models.BooleanField(default=False)#性别,BooleanField说明是bool类型,default指定默认值,False代表男
#备注
hcomment=models.CharField(max_length=128)
# 关系属性,建立图书和物一对多关系
# 关系属性对应的表的字段名格式:关系属性名_id(外键)
hbook=models.ForeignKey(to="BookInfo",on_delete=models.CASCADE)
def __str__(self):
# 返回名字
return self.hname
?
4)自定义管理页面
自定义模型管理类,模型管理类就是生成django在生成的管理页面上显示哪些内容
?admin.py
from django.contrib import admin
from index.models import BookInfo,HeroInfo
# 后台管理相关文件
# Register your models here.
#自定义模型管理类
#图书模型管理类
class BookInfoAdmin(admin.ModelAdmin):#继承于admin.ModelAdmin
# list_display页面显示的内容
list_display=['id','btitle','bpub_date']#类属性
#英雄人物管理类
class HeroInfoAdmin(admin.ModelAdmin):
list_display = ['id', 'hname', 'hcomment']
#注册模型类:只能各写一个,不能重复写
admin.site.register(BookInfo,BookInfoAdmin)
admin.site.register(HeroInfo,HeroInfoAdmin)
?
?
?
?
视图
?在Django中,通过浏览器去请求一个页面时,使用视图函数来处理这个请求的,视图函数处理之后,要给浏览器返回页面内容
视图函数的使用
1)定义视图函数
视图函数定义在views.py中
index/urls.py
from django.urls import path
from . import views
# 创建一个列表
# url地址和视图的对应
urlpatterns=[
# 通过url函数设置url路由配置项,要先在项目的urls中加配置项
# 建立/index和视图index之间的关系
path('index',views.index), #左边index:index文件夹。括号内为地址和地址对应的视图
path('index2',views.index2),
]
Mydjango/urls.py
from django.urls import path
from django.conf.urls import include, url
from django.contrib import admin
# 项目的urls文件#这里容易报错
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('index.urls')),#包括booktest应用中的url文件
]
views.py
from django.http import HttpResponse
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M和T进行交互
return HttpResponse('hello~') # 返回给浏览器
def index2(request):
# 进行处理,和M和T进行交互
return HttpResponse('你好~') # 返回给浏览器
python manage.py runserver
?
?
?模板的使用
新建文件夹
?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板文件</title>
</head>
<body>
<h1>这是一个模板文件,{{ content }}</h1>
</body>
</html>
?
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader,RequestContext
def my_render(request, template_path, context_dict={}):
#使用模板文件
#1.加载模板文件,模板对象
temp=loader.get_template(template_path)
#2.定义模板上下文:给模板文件传递数据
# context=RequestContext(request,context_dict)#这个会报错
context =context_dict
#3.模板渲染:产生标准的html内容
res_html=temp.render(context)
#4.返回给浏览器
return HttpResponse(res_html)
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M和T进行交互
# return HttpResponse('hello~') # 返回给浏览器
return my_render(request,'index/index.html',{'content':'hello word'})
index/urls.py
from django.urls import path
from . import views
# 创建一个列表
# url地址和视图的对应
urlpatterns=[
# 通过url函数设置url路由配置项,要先在项目的urls中加配置项
# 建立/index和视图index之间的关系
path('index',views.index), #左边index:index文件夹。括号内为地址和地址对应的视图
]
?
?连接数据库
新建html
?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>显示图书</title>
</head>
<body>
{% for book in books %}
<li>{{ book.btitle }}</li>
{% endfor %}
</body>
</html>
#views.py
from django.shortcuts import render
from index.models import BookInfo#导入图书模型类
from django.http import HttpResponse
from django.template import loader,RequestContext
def my_render(request, template_path, context_dict={}):
#使用模板文件
#1.加载模板文件,模板对象
temp=loader.get_template(template_path)
#2.定义模板上下文:给模板文件传递数据
# context=RequestContext(request,context_dict)#这个会报错
context =context_dict
#3.模板渲染:产生标准的html内容
res_html=temp.render(context)
#4.返回给浏览器
return HttpResponse(res_html)
# Create your views here.
# 1.定义视图函数,HttpRequest
# 2.进行url配置,建立url地址和视图的对应关系
# http://127.0.0.1:8000/index
def index(request):
# 进行处理,和M和T进行交互
# return HttpResponse('hello~') # 返回给浏览器
return my_render(request,'index/index.html',{'content':'hello word'})
def index2(request):
# 进行处理,和M和T进行交互
return HttpResponse('你好~') # 返回给浏览器
def show_books(request):
books=BookInfo.objects.all()
return render(request,'index/show_books.html',{'books':books})
#MyDjango/urls.py
from django.urls import path
from django.conf.urls import include
from django.contrib import admin
# 项目的urls文件
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('index.urls')),#包括booktest应用中的url文件
#index/urls.py
from django.urls import path
from . import views
# 创建一个列表
# url地址和视图的对应
urlpatterns=[
# 通过url函数设置url路由配置项,要先在项目的urls中加配置项
# 建立/index和视图index之间的关系
path('index',views.index), #左边index:index文件夹。括号内为地址和地址对应的视图
path('index2',views.index2),
path('books',views.show_books),#显示图书信息
]
?
??
?
?图来自极客视频
以下是《Django3 web应用开发实战-黄永祥》章节总结
二、Django配置信息
(一)资源文件配置
Django配置文件settings.py:用于配置整个网站的环境和功能。
核心配置:项目路径、密钥配置、域名访问权限、App列表、中间件、资源文件、模板配置、数据库的连接方式。
资源文件配置
先建4个文件夹,放一些图片进去,名字如图
这里有两个static文件,系统默认的是index下的static文件
静态资源文件
settings.py文件中先在INSTALLED_APPS注册应用index,第39行。
然后配置静态文件信息 ,添加以下代码119行——123行
"""
Django settings for MyDjango project.
Generated by 'django-admin startproject' using Django 3.2.9.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path
# 项目目录的绝对路径。主要通过os模块读取当前项目在计算机系统的具体路径。
# 创建项目时系统自动生成,一般不用改。
BASE_DIR = Path(__file__).resolve().parent.parent
# 密钥配置。用于重要数据的加密处理,提高项目的安全性。
# 密钥主要用于用户密码(Auth认证系统,将用户密码加密)、CSRF机制(表单提交,防窃取用户信息制造恶意请求)和会话Session(存放在Cookie中)等数据加密。
# 创建项目时系统自动生成随机值,一般不用改。
SECRET_KEY = 'django-insecure-70+4nbazxyc#v6l5axu=l29yf-(69)-8&jo4*wu=t^i2vt$_71'
# 调试模式,开发阶段为True,项目部署上线就要改为False,否则会泄露项目相关信息。
DEBUG = True
# 域名访问权限。设置可访问的域名,当DEBUG = True,ALLOWED_HOSTS = []空列表时,项目只允许localhost在浏览器访问。
# 当DEBUG = False,ALLOWED_HOSTS = 必填,否则程序无法启动。如果要所有域名都可以访问可设为ALLOWED_HOSTS = [‘*’]
ALLOWED_HOSTS = []
# App列表
INSTALLED_APPS = [
'django.contrib.admin', # 内置的后台管理系统
'django.contrib.auth', # 用户认证系统
'django.contrib.contenttypes', # 记录项目中所有model元数据(orm框架)
'django.contrib.sessions', # 会话功能,标识当前访问网站用户身份,记录相关用户信息
'django.contrib.messages', # 消息提示功能
'django.contrib.staticfiles', # 查找静态资源路径
'index' # 在项目中创建了app,就必须在这列表里添加app名称
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'MyDjango.urls'
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',
],
},
},
]
WSGI_APPLICATION = 'MyDjango.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
# LANGUAGE_CODE = 'en-us'#后台管理中的本地化语言,中文:zh-hans
LANGUAGE_CODE = 'zh-hans'
# TIME_ZONE = 'UTC' 使用国际标准时间UTC:
# 所有时间在存入数据库前,必须转换成UTC时间。当使用时区时,Django存储在数据库中的所有日期时间信息都以UTC时区为准,在后台使用有时区的datetime,前台用户使用时,在网页上翻译成用户所在的时区。
# 后台向数据库输入日期时间时,日期时间应该带有时区信息,如果没有,输入数据库时会有警告
TIME_ZONE = 'Asia/Shanghai' # 中国时间:Asia/Shanghai
USE_I18N = True
USE_L10N = True
USE_TZ = True
# # Static files (CSS, JavaScript, Images)。
# # 静态资源的路由地址:通过浏览器访问Django的静态资源。查找功能由App列表——INSTALLED_APPS——staticfiles
STATIC_URL = '/static/'
# # 设置根目录的静态资源文件夹static
STATICFILES_DIRS = [BASE_DIR / 'static',
# 设置App(index)的静态资源文件夹Mystatic
BASE_DIR / 'index/Mystatic', ]
# 资源部署:在服务器上部署项目,实现服务器和项目之间的映射。STATIC_ROOT主要收集整个项目的静态资源并存放在一个新的文件夹,由该文件夹与服务器之间构建映射关系。
# 项目部署上线DEBUG = False,Django不在提供静态文件代理服务,需要设置STATIC_ROOT。项目开发阶段就不需要设置,会自动提供。
# STATIC_ROOT=BASE_DIR/'AllStatic'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
运行一下python manage.py runserver 8000
STATIC_URL名字(static)就是指浏览器网址地址,所以和网址名字.../static/....对应。
打开浏览器输入网址,就可以看到图片了。
媒体资源文件
先配置媒体资源属性,然后注册到Django里。
settings.py文件下添加以下代码
# 媒体资源配置
# 设置媒体路由地址信息
MeDIA_URL='/media/'
# 获取media文件夹的完整路径信息
MEDIA_ROOT=BASE_DIR/'media'
MyDjango—urls.py文件如下
from django.urls import path,re_path
from django.conf.urls import include
from django.contrib import admin
from django.views.static import serve
from django.conf import settings
# 项目的urls文件
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('index.urls')),
# 配置媒体文件的路由地址
re_path('media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT},name='media'),
]
(二)templates模板配置
模板是Django里面的MTV框架模式的T部分,配置模板路径是在解析模板时,找到模板的所在的位置。
模板配置通常配置DIRS的属性即可。
创建两个templates文件夹,并在文件夹下分别创建两个html
一般根目录的templates存放共用模板文件
settings.py文件模板配置如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates', # 定义模板引擎,用于识别模板里面的变量和指令。内置模板引擎有Django Templates和jinja2.Jinja2,每个模板引擎都有自己的变量和指令语法。
#注册根目录和index的templates文件夹
'DIRS': [os.path.join(BASE_DIR, 'templates',
BASE_DIR, 'index/templates')], # 设置模板文件路径,每个模板引擎都有自己的变量和指令语法。
'APP_DIRS': True, # 是否在App里查找模板文件
'OPTIONS': { # 用于填充在RequestContext的上下文(模板里面的变量和指令),一般情况下不做修改
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
(三)数据库配置
1、mysqlclient连接mysql
Django提供4种数据库引擎
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.sqlite3
django.db.backends.oracle
下载mysqlclient,版本要和Python版本相匹配
https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
安装pip install E:\1203\mysqlclient-1.4.6-cp39-cp39-win_amd64.whl
?
?在settings.py中配置MySQL数据库连接信息,
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',#选择的数据库引擎mysql
'NAME': 'django_db', # 创建默认Sqlite3,轻型数据库,用于切入式系统开发,占用资源少
'USER':'root',
'PASSWORD':'1234',
'HOST':'127.0.0.1',
'PORT':'3306',
}
}
新建一个数据库
创建Django内置功能(如Admin后台系统、Auth用户系统和会话机制等功能)的数据表:python manage.py migrate将内置的迁移文件生成数据表
就可以看到在数据库中已经生成相应的表了
?
注意Django对应的mysqlclient的版本要求,
?如果发现mysqlclient版本过低,可以将if条件判断注释。
2、pymysql连接MySQL
pip install pymysql
?settings.py数据库配置不用改,在MyDjango文件夹中的__init__.py中设置数据库连接模块即可。
import pymysql
pymysql.install_as_MySQLdb() # 设置数据库连接模块
3、多个数据库的连接方式
# 数据库配置
DATABASES = {
# 第一个数据库,default是默认的数据库不可删除,可留空{}
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_db',
'USER':'root',
'PASSWORD':'1234',
'HOST':'127.0.0.1',
'PORT':'3306',
},
# 第二个数据库
'MyDjango': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydjango_db',
'USER': 'root',
'PASSWORD': '1234',
'HOST': '127.0.0.1',
'PORT': '3306',
},
# 第三个数据库
'MySqlite3': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR/'django_db', # BASE_DIR,数据库在项目路径下生成
},
}
4、使用配置文件动态连接数据库
在MyDjango目录下创建配置文件my.cnf,写入MySOL数据库的连接信息。
[client]客户端设置,即客户端默认的连接参数
[client]
database=django_db
user=root
password=1234
host=127.0.0.1
port=3306
在settings.py写配置信息。default--OPTIONS--read_default_file中设置配置文件my.cnf的路径,Django读取配置文件my.cnf的数据库连接信息,连接数据库。
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {'read_default_file':str(BASE_DIR / 'my.cnf')},
},
}
在MyDjango的urls.py中设置路由index,路由的视图函数indexView()在项目应用index的view.py中定义。
from django.urls import path
from django.contrib import admin
from index.views import index # 导入项目应用index
# 项目的urls文件
urlpatterns = [
path('admin/', admin.site.urls),
path('',index,name='index'),
]
在项目应用index的view.py中定义路由index的视图函数indexView()。
?indexView()读取并输出Django内置函数ContentType的数据,请求响应的内容为templates文件夹的app_index.html
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
def indexView(request):
c=ContentType.objects.values_list().all()
print(c)
return render(request,'app_index.html')
app_index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<span>Hello World!!</span>
</body>
</html>
python manage.py migrate
?python manage.py runserver 8001
5、通过SSH隧道远程连接MySQL
?先在SSH栏设置,然后在常规栏设置。
?
?pip install sshtunnel
?下载sshtunnel,通过SSH方式连接到目标服务器,生成服务器的SSH连接对象,在settings.py文件的DATABASES中设置数据库连接
# ssh_:实现SSH连接目标服务器,在sshtunnel模块中使用
# 数据库服务器的ip地址或主机名
ssh_host = "192.168.xx.xx"
# 数据库服务器的SSH连接端口号,一般都是22,必须是数字
ssh_port = 22
# 数据库服务器的用户名
ssh_user = "root"
# 数据库服务器的用户密码
ssh_password = "1234"
# mysql_:在目标服务器基础上连接MySQL数据库,在配置属性DATABASES和sshtunnel模块中均被使用
# 数据库服务器的mysql的主机名或ip地址
mysql_host = "localhost"
# 数据库服务器的mysql的端口,默认为3306,必须是数字
mysql_port = 6603
# 数据库服务器的mysql的用户名
mysql_user = "root"
# 数据库服务器的mysql的密码
mysql_password = "1234"
# 数据库服务器的mysql的数据库名
mysql_db = "mydjango"
# 分别定义服务器的SSH连接信息和数据库的连接信息
# 定义服务器的SSH连接函数get_ssh(),使用sshtunnel模块的open_tunnel函数实现,并设置相应的函数参数
from sshtunnel import open_tunnel
def get_ssh():
server = open_tunnel(
(ssh_host, ssh_port),
ssh_username=ssh_user,
ssh_password=ssh_password,
# 绑定服务器的MySQL数据库
remote_bind_address=(mysql_host, mysql_port))#remote_bind_address是绑定服务器的MySQL数据库
# ssh通道服务启动
server.start()
return str(server.local_bind_port)
# 在DATABASES的PORT中调用get_ssh(),Django就会连接到服务器的MySQL数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': mysql_db,
'USER': mysql_user,
'PASSWORD': mysql_password,
'HOST': mysql_host,
'PORT': get_ssh(),
}
}
(四)路由
路由(一)路由配置
步骤:
- 创建项目
- settings.py文件配置(注册index和TEMPLATES)
- 新建一个index.html
- 路由配置:MyDjango文件夹的urls.py、index的urls.py、index 的views.py
-
运行python manage.py runserver,打开网址
1、创建项目
django-admin startproject 项目名
cd?项目名
python manage.py startapp 应用名
2、settings.py文件中,注册index
?3、新建一个文件夹templates,新建一个index.html,并在settings.py文件的TEMPLATES添加DIRS
'DIRS': [os.path.join(BASE_DIR, 'templates')]
4、路由配置
完整路由:路由地址、视图函数(视图类)、可选变量、路由命名。
路由编写规则和使用方法:路由定义规则、命名空间与路由命名、路由的使用方式。
在index文件夹里添加一个空白内容的urls.py文件,是将所有属于index应用的路由都写入该文件。
MyDjango文件夹的urls.py如下:
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
# 两个路由:一个Admin站点管理(创建时已自动生成,一般不用改),一个首页地址index(index文件夹下的urls.py),
urlpatterns = [
# 'admin/'代表127.0.0.1:8000/admin的路由地址,admin.site.urls指向内置Admin功能所定义的路由信息
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
# '' 代表路由地址为’\‘,即127.0.0.1:8000,一般是网站首页,路由函数include是将该路由信息分发给index的urls.py处理。
path('', include('index.urls')), # 指向index的路由文件urls.py
]
index的urls.py导入index的views.py文件,views.index是指视图函数的index处理网站首页用户的用户请求和响应过程。路由信息如下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index)
]
index 的views.py文件用于编写视图函数或视图类,主要处理当前请求信息并返回响应内容给用户。处理过程如下:
from django.shortcuts import render
# Create your views here.
def index(request): # index函数必须要设置一个参数,常用request,表示当前用户的请求对象,该对象包含当前请求的用户名、请求内容和请求方式等。
value = 'This is test!'
print(value)
return render(request, 'index.html') # 必须要返回处理结果
5、运行python manage.py runserver
打开浏览器访问网址
?路由(二)路由变量、正则路由定义、命名空间和路由命名
1、设置路由变量
路由变量类型:字符类型、整型、slug(注释、后缀或附属等,常作为路由解释性字符)和uuid(匹配一个uuid格式的对象,用‘-’且字母必须为小写)。
先创建项目MyDjango,新建应用index
然后注册应用在settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index', # 注册应用
]
MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
# 两个路由:一个Admin站点管理(创建时已自动生成,一般不用改),一个首页地址index(index文件夹下的urls.py),
urlpatterns = [
# 'admin/'代表127.0.0.1:8000/admin的路由地址,admin.site.urls指向内置Admin功能所定义的路由信息
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
# '' 代表路由地址为’\‘,即127.0.0.1:8000,一般是网站首页,路由函数include是将该路由信息分发给index的urls.py处理。
path('', include('index.urls')), # 指向index的路由文件urls.py
]
在MyDjango项目的index文件夹的urls.py里新定义路由
from django.urls import path
from . importfrom django.urls import path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
path('<year>/<int:month>/<slug:day>', views.myvariable)
]
views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
path('<year>/<int:month>/<slug:day>', views.myvariable)
]
index的views.py编写myvariable视图函数的处理过程
from django.http import HttpResponse
# Create your views here.
def myvariable(request, year, month, day):return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))
启动项目python manage.py runserver,打开浏览器输入网址127.0.0.1:8000/?字符型 / 整型 / slug,如果变量类型不符会报错
添加路由地址外的变量 在MyDjango项目的index文件夹的urls.py
from django.urls import path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
path('<year>/<int:month>/<slug:day>', views.myvariable),
# 添加路由地址外的变量month,参数只能以字典的形式表示
path('',views.index,{'month':'2025/10/10'})
]
index的views.py
from django.http import HttpResponse
# Create your views here.
def myvariable(request, year, month, day):
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))
def index(request,month):
return HttpResponse('这是路由地址之外的变量:'+month)
2、正则表达式路由定义
?在MyDjango项目的index文件夹的urls.py
re_path定义路由函数正则表达式
(?P<year>[0-9]{4})以小括号为单位,?P必须大写,<year>为变量,长度4,只取0~9
.html:将网址设为静态网址,为变量终止符
from django.urls import re_path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
re_path('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2}).html', views.myvariable)
]
?没有.html则可在最后一个变量之后无限输入字符串
3、命名空间和路由命名
在刚刚文件夹上新建一个应用user,这样这里就有两个应用了:index和user
?MyDjango下的urls
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
# 3个路由:一个Admin站点管理(创建时已自动生成,一般不用改),一个index文件夹下的urls.py),一个user文件下的urls.py
urlpatterns = [
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
path('', include(('index.urls','index'), namespace='index')), # 指向index的路由文件urls.py
path('user/', include(('user.urls', 'user'), namespace='user')) # 指向user的路由文件urls.py
]
index下的urls.py
from django.urls import re_path,path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
re_path('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', views.mydate),
path('',views.index,name='index')
]
index下的views.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def mydate(request, year):
return HttpResponse(str(year))
def index(request):
return render(request,'index.html')
user下的urls.py
from django.urls import path
from . import views
urlpatterns = [
path('index', views.index, name='index'),
path('login', views.userLogin, name='userLogin')
]
user下的views.py
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("this is test userindex!")
def userLogin(request):
return HttpResponse("this is test userLogin!")
不同项目应用的路由命名是可以重复的,namespace是路由函数include的可选参数,路由命名name是路由函数path或re_path的可选参数。include中如果设置name是没有实质作用的,所以没必要设。Django的路由名name是对路由进行命名的,作用是在开发中可以在视图或模板等其他功能模块里使用路由命名name来生成路由地址。
路由(三)路由的使用方式
-
在模板中使用路由 -
反向解析reverse与resolve -
路由重定向
在《精通Django 3 Web开发3.1设置路由分发规则》中写到:
从MyDjango文件夹的urls.py定义的路由信息得知,每个项目应用(App)的路由地址交给项目应用的urls.py自行管理,这是路由的分发规则,使路由按照一定的规则进行分类管理。整个路由设计模式的工作原理说明如下:
(1)当运行babys项目时,Django从babys文件夹的urls.py找到各个项目应用(App)的urls.py,然后读取每个项目应用(App)的urls.py定义的路由信息,从而生成完整的路由列表。
(2)用户在浏览器上访问某个路由地址时,Django就会收到该用户的请求信息。
(3)Django从当前请求信息中获取路由地址,并在路由列表里匹配相应的路由信息,再执行路由信息所指向的视图函数(或视图类),从而完成整个请求响应过程。
django的路由命名name是对路由进行命名,其作用是在开发过程中可以在视图或模板等其他功能模块里使用路由命名name来生成路由地址。
命名空间namespace可以为我们快速定位某个项目应用的urls.py,再结合路由命名name就能快速地从项目应用的urls.py找到某条路由的具体信息,这样就能有效管理整个项目的路由列表。
1、在模板中使用路由
不设置命名空间namespace
# MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
urlpatterns = [
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
path('', include('index.urls')), # 指向index的路由文件urls.py
]
# index的urls.py
from django.urls import path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),
path('',views.index)
]
#index的views.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def mydate(request, year,month,day):
return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))
def index(request):
return render(request,'index.html')
#templates的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello word!
<a href="{% url 'mydate' '2022' '01' '28' %}">查看日期</a>
</body>
</html>
模板语法url来生成路由地址
{% url 'mydate' '2022' '01' '28' %}中的mydate代表命名为mydate的路由,即index的urls.py设有字符类型、整型和slug的路由。
?
?设置命名空间namespace
# Django的urls.py
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
urlpatterns = [
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
path('', include('index.urls')), # 指向index的路由文件urls.py
path('', include(('index.urls', 'index'), namespace='index')),
]
#templates的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello word!
{# <a href="{% url 'mydate' '2022' '01' '28' %}">查看日期</a> #}
<a href="{% url 'index:mydate' '2022' '01' '28' %}">查看日期</a>
</body>
</html>
路由在定义过程中使用命名空间namespace,模板语法url也要添加命名空间。
如:'命名空间namespace:命名路由name'
2、反向解析reverse与resolve
反向解析:用户浏览网站,Django根据网址在路由列表里查找相应的路由,再从路由里找到视图函数或视图类进行处理,将处理结果作为响应内容返回给浏览器并生成网页内容。这是不可逆的,在视图里使用路由则为反向解析。 反向解析由函数reverse和resolve实现。
reverse通过路由命名或可调用视图对象来生成路由地址的;
resolve通过路由地址来获取路由对象信息的。
在使用这两个函数时,需要注意两者所传入的参数类型和返回值的数据类型。 MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include # 导入Django的路由函数模块
# urlpatterns代表整个项目的路由集合
urlpatterns = [
path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py
path('', include(('index.urls', 'index'), namespace='index')),
]
index的urls.py
from django.urls import path
from . import views
# 路由命名为index和mydate
urlpatterns = [
# 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。
path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),
# 定义首页的路由
path('',views.index,name='index')
]
index的views.py
from django.http import HttpResponse
from django.shortcuts import reverse
from django.urls import resolve
# Create your views here.
def mydate(request, year, month, day):
args = ['2022', '01', '29']
result = resolve(reverse('index:mydate', args=args))
print('kwargs:', result.kwargs)
print('url_name:', result.url_name)
print('namespace:', result.namespace)
print('view_name:', result.view_name)
print('app_name:', result.app_name)
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))
# index主要使用反向解析函数reverse来生成路由mydate的路由地址。
def index(request):
kwargs = {'year': 2022, 'month': 2, 'day': 10}
args = ['2022', '01', '29']
# 使用reverse生成路由地址
print(reverse('index:mydate', args=args))
print(reverse('index:mydate', kwargs=kwargs))
return HttpResponse(reverse('index:mydate', args=args))
python manage.py runserver
启动服务器后会调用views中index函数
按住ctrl键点击上面的views.py中的reverse,可查看reverse的源码
- viewname:代表路由命名或可调用视图对象,一般情况下是以路由命名name来生成路由地址的。
- urlconf:设置反向解析的URLconf模块。默认情况下,使用配置文件settings.py的ROOT_URLCONF属性(MyDjango文件夹的urls.py)
- args:以列表方式传递路由地址变量,列表元素顺序和数量应与路由地址变量的顺序和数量一致。
- kwargs:以字典方式传递路由地址变量,字典的键必须对应路由地址变量名,字典的键值对数量与变量的数量一致。
- current_app:提示当前正在执行的视图所在的项目应用,主要起到提示作用,在功能上并无实质的作用。
内置的函数方法:
函数方法 | 说明 | func | 路由的视图函数对象或视图类对象 | args | 以列表格式获取路由的变量信息 | kwargs | 以字典格式获取路由的变量信息 | url_name | 获取路由命名(name) | app_name | 获取项目路由函数include的参数arg的第二个元素值 | app_names | 与app_name功能一致,但以列表格式表示 | namespace | 获取命名空间(namespace) | namespaces | 与namespace功能一致,但以列表格式表示 | view_name | 获取整个路由名称,格式:namespace:name |
3、路由重定向
重定向:HTTP协议重定向,也称为网页跳转,就是在浏览器访问某个网页的时候,这个网页不提供响应内容,而是自动跳转到其他网址,由其他网址来生成响应内容。
django的网页重定向有两种方式:第一种方式时路由重定向;第二种方式是自定义视图的重定向。两种重定向方式各有千秋,前者是使用django内置的视图类RedirectView实现的,默认支持HTTP的GET请求;后者是在自定义视图的响应状态设置重定向,能让开发者实现多方面的开发需求。
index的urls.py
from django.urls import path
from . import views
from django.views.generic import RedirectView
urlpatterns = [
# 添加带有字符类型、整型和slug的路由
path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'),
# 定义首页的路由
path('', views.index, name='index'),
# 设置路由跳转
path('turnTo', RedirectView.as_view(url='/'), name='turnTo'),
]
在路由里使用视图类RedirectView必须使用as_view方法将视图实例化,参数url用于设置网页跳转的路由地址,“/”表示网站首页(路由命名为index的路由地址),然后在index的view.py定义视图函数mydate和index
index的view.py
from django.http import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import reverse
def mydate(request, year, month, day):
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day))
def index(request):
print(reverse('index:turnTo'))
return redirect(reverse('index:mydate', args=[2019,12,12]))
视图函数index是使用重定向函数redirect实现网页重定向的,函数参数只需传入路由地址即可实现重定向。
模板语法url的参数设置与路由定义是相互关联的:
- 若路由地址存在变量,则模板语法url需要设置响应的参数值,参数值之间使用空格隔开。
- 若路由地址不存在变量,则模板语法url只需设置路由命名name即可,无须设置额外的参数。
- 若路由地址的变量与模板语法url的参数数量不相同,则在浏览器访问网页的时候会提示NoReverseMatch at的错误信息
|