# 开发环境
python3.7
django
win10(64 位)
# 什么是框架
通俗的说,框架是实现某种功能的半成品,提供了一些常用的工具类和一些基础通用化的组件,可以供开发人员在此基础上,更高效的满足各自的业务需求。
# 为什么要使用框架
一个优秀的的框架,它相当于是一个模板代码库,很多基础性的功能,底层功能操作都已经帮我们实现了,我们只需要专心的实现所需要的业务逻辑就可以了。这样,就大大提高了我们的开发效率,所以技术的发展,多数情况下是为了满足业务的需求。
简单,快捷,高效,响应,兼容
# 什么是 django
我们都知道,Django 是基于 Python 的 Web 开发框架。
百度百科介绍:
Django 是一个开放源代码的 Web 应用框架,由 Python 写成。采用了 MTV 的框架模式,即模型 M,视图 V 和模版 T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是 CMS(内容管理系统)软件。并于 2005 年 7 月在 BSD 许可证下发布。
这套框架是以比利时的吉普赛爵士吉他手 Django Reinhardt 来命名的。
有一家劳伦斯的出版社,说白了就想新浪。这种网站会涉及到什么问题呢我们来看一下:
只需进行数据库替换,采用此模板样式不变,那网站的开发速率提高
# django 目的和用途
django 的主要目的是简便,快速的开发数据库驱动的网站,他强调代码复用。
多个组件看依方便的以 “插件” 形式服务整个框架
所有的 web 框架的意义都在于:
- 搭建框架应用
- 免去不同 web 应用相同代码的部分重复编写,只需关心应用核心的业务实现
}}}
}}}
# django 的特点
对比 Flask 框架,Django 原生提供了众多的功能组件,让开发更便捷
- 提供项目工程管理的自动脚手工具(脚手架工具)
- 数据库 ORM 支持(对象关系映射)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 (img-GygyZD04-1632645131208)(assets/image-20210921214755-gc5rj3l.png)]【不会 sql 语句也可以实现】
- 模板【replace,可以通过变量将模板和数据打通。使用数据替换模板变量,达到动态展示效果】
- 表单【表单获取直接转化成对象处理】
- admin 管理站点【自动生成后台】
- 文件管理
- 认证权限
- session 机制
- 缓存
如果 Django 类似于精装修的房子,自带豪华家具、非常齐全功能强大的家电,什么都有了,拎包入住即可,十分方便。重量级框架,快捷。
而 Flask 类似于毛坯房,自己想把房子装修成什么样自己找材料,买家具自己装。材料和家具种类非常丰富,并且都是现成免费的,直接拿过去用即可。轻量级,灵活。
# MVT 设计模式
前端客户端发起请求,请求可能是用户点击浏览器发起的,app,ajax 请求或是爬虫程序,
服务器:接受和解析 http 请求报文,他的服务对象是 http 请求
框架:后端服务框架,服务器解析成字典格式
视图:定义数据处理方法:index()然后经处理完的结果变成响应对象,发送给服务器
中间层:装饰器
作用:在不添加源代码的情况下增加功能
#补充知识点#
((20210923102902-68l094i))
WSGI 只是一个 PythonWeb 服务器网关接口协议,或者说是一份标准,用来描述 Server 与 Framework 之间的通信接口。
这样,一些符合 WSGI 标准的 Framework 如 Flask、Django、web.py 等等就可以与同样符合 WSGI 标准的 Server 库进行无缝对接。
只要你的 Framework 符合 WSGi 规范,那么在以后有了效率更高的 Server 的时候,你可以毫不费力地将代码迁移过去。
#场景 #:开发了几个应用后,发现每个应用都完成了从监听网络端口到建立连接、解析请求的参数、进行回应、发送 Response 数据包等等一系列的工作,每次都要在获取请求、解析请求、发送请求这些一成不变的步骤上花费大量时间,不如写个 Server 模块,把这些功能单独实现,以后再有新的需求,只需要考虑 Framework 部分即可,这样就可以避免 “重复造轮子” 了。当自己写好了一套 server 程序,隔壁老王听说你写了个 Server 程序很牛掰,想要借用一下你的代码。你本着开源精神将 Server 模块分享给他,可是,老王拿到代码一看就傻眼了 —— 天啊,你的 Server 部分的数据接口、函数调用方式和他自己写的 Framework 完全不搭,改动起来难度颇大,还不如自己再写一个 Server 来得方便。应该整一套接口规范出来,让老王在编写自己的 Framework 的时候就按照你设计的规范来写,这样写出来的程序才能够互相 “契合”,便于调试和使用。就是 WSGI(Python Web Server Gateway)
# MVC
程序设计模式:MVC,核心思想 **:分工,解耦 **,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容
M 全拼为 Model,主要封装对数据库的访问,对数据库中数据进行增删改查操作
V 全拼为 View,用于封装结果,生成页面展示的 html
C 全拼 Controller,用于接收请求,处理业务逻辑,与 Model 和 View 进行交互,返回结果
# MVT
原理就是 mvc 不过自己将名字改了
M 全拼为 Model,与 MVC 中的 M 功能相同,主要封装对数据库的访问,对数据库中数据进行增删改查操作
V 全拼为 View,与 MVC 中的 C 功能相同,用于接收请求,处理业务逻辑,与 Model 和 View 进行交互,返回结果
T 全拼 Template,与 MVC 中的 V 功能相同,用于封装结果,负责封装构造要返回的 html
((20210924115549-5h51jh6))
# 虚拟环境
# 什么场景需要用虚拟环境
比如两个项目在并行,然后用到的 python 和 django 版本不一样
解释器一样包都可能不一样
# 虚拟环境效果
[
((20210923111014-udk4aum))
# 实战
# 搭建环境
默认会下载最新版本
pip install django
# 创建工程
进入想要创建的项目目录下
再命令行中输入
django-admin startproject todo
查看文件
采用 pycharm 打开项目
然后进入项目中
cd todo
尝试启动服务器
在开发阶段,未来能够快速预览到开发效果
django 提供了一个纯 python 编写的轻量级 web 服务器,仅在开发阶段使用。
python manage.py runserver
这样这是成功
python manage.py migrate
# 创建管理员账号
python manage.py createsuperuser
重新启动服务器:
登陆刚注册号的账号密码
进入数据管理页面 http://localhost:8000/admin
终止服务器, Ctrl+C
# 创建子应用
python manage.py startapp tasks
查看目录中的结构
# 配置 app 路径
然计算机找到创建的 app
在添加
'tasks'
查找定位到 app 的路径
跟项目路径:
之前 django2.x
BASE_DIR =as.path.dirname(os.path.dirname(os.path.abspath(__file__)))
引入 path 之后
BASE_DIR = Path(__file__).resolve().parent.parent
C:\Users\yangs\Desktop\ 新建文件夹 \todo\todo\settings.py
# 创建视图函数
再 app tasks 中创建视图函数 view index
from django.shortcuts import render
from django.http import HttpResponse
## Create your views here.
def index(request):
return HttpResponse('hello djangho')
# 创建 urls 路由
# 配置项目 urls
"""todo URL Configuration The `urlpatterns` list routes URLs to views.
For more information please see: https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples: Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('tasks.urls')) ]
# 重启服务器
重新启动服务器 python manage.py runserver
# 创建模板
创建文件夹 templates 中再创建 tasks 文件夹中创建 list.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 (img-Yhxl9wbo-1632645131300)(assets/clipboard-20210921230301-1lv02wo-20210924095934-379n9oy.png)]
<h3>TODO</h3> |
# 修改视图
修改 app tasks 中的 views
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return render(request,'tasks/list.html')
此时出现
别着急看看错误提示
# 配置模板默认路径
显示找不到 list.html 文件,所以我们将从配置 setting 中设置
"""
Django settings for todo project.
Generated by 'django-admin startproject' using Django 3.2.6.
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
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-+(9j8^8xt6(5aa79o^bp8g8#t#lpuif3u424yx55bz=yrk@)d%'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tasks',
]
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 = 'todo.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 = 'todo.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'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
此时刷新一下:
# 创建模型
之后我们来创建 model 文件
from django.db import models
# Create your models here.
class Task(models.Model):
title=models.CharField(max_length=200)
complete=models.BooleanField(default=False)
create=models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
再命令行中输入:
# 更新数据库
python manage.py makemigrations
python manage.py migrate
将数据库进行更新
# 启动服务器:
python manage.py runserver
访问 8000:/admin
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 (img-KLguiQfn-1632645131322)(assets/clipboard-20210921230301-svzfg5q-20210924095934-vw2uo7h.png)]" />
没有发现新建的 model
# 用户和 model 进行关联
需要将用户和 model 进行关联
在 app tasks 中 admin 中
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Task)
重新刷新页面
其中新创建的模块
# 添加数据库数据
添加数据并在数据库中查看数据:
<br />
现在我们想要将数据库中的数据显示在 views 中
将 models 中映射的数据放在 view 中展示出来
# 展示数据
# 修改 view
在 app tasks 中 view 修改
from django.shortcuts import render
from django.http import HttpResponse
from .models import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
context={'tasks',tasks}
return render(request,'tasks/list.html',context)
# 修改 html
将数据传入模板当中
list.html
<h3>TO DO</h3> | |
在 app tasks 中创建 form 文件
# 创建 form
from django import forms
from django.forms import ModelForm
from .models import *
class TaskForm(forms.ModelForm):
class Meta:
model=Task
fields='__all__'
# 修改 view
在 view 中更改:
from django.shortcuts import render
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
<br />
# 更改模板文件:
<h3>TO DO</h3>
<form>
{{form}}
<input type="submit" name="create Task">
</form>
{% for task in tasks %}
{{task.title}}
{% endfor %}
查看页面:
# 添加数据
# 修改模板 html 页面:
<h3>TO DO</h3>
<form method="POST" action="/">
{{form}}
<input type="submit" name="create Task">
</form>
{% for task in tasks %}
{{task.title}}
{% endfor %}
<br />
<br />
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
启动发现:
输入数据点击提交
此时我们设置一下 list,html
# 修改 html
<h3>TO DO</h3>
<form method="POST" action="/">
#csrf_token #数据发送django自带保护机制
{{form}}
<input type="submit" name="create Task">
</form>
{% for task in tasks %}
{{task.title}}
{% endfor %}
在页面上测试添加
成功,现在我们来编写
# 修改页面
先在模板下创建 update_task.html 页面
# 修改 html
<h3>Update Task</h3>
<form>
<input type="submit" name="Update Task">
</form>
# 修改 view
在 views 页面中进行修改:
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.all(id=pk)
return render(request,'tasks/update_task.html')
<br />
# 修改 url
修改 app task 中的 urls
from django.urls import path | |
from . import views | |
app_name = 'tasks' | |
urlpatterns = [ | |
path('', views.index, name='list'), | |
path('update_task/<str:pk>',views.updateTask,name='update_task'), | |
] |
接着我们需要在修改页面写入响应的数据和输入框
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.get(id=pk)
form=TaskForm(instance=task)
context={'form':form}
return render(request,'tasks/update_task.html',context=context)
# 修改 html
修改模板 update_task 页面:
<h3>Update Task</h3> | |
<form> | |
<input type="submit" name="Update Task"> | |
</form> |
页面显示
<br />
这里只是显示出来还不能修改
修改页面
<h3>Update Task</h3>
<form method="post" action="">
{{form}}
<input type="submit" name="Update Task">
</form>
# 修改 view 文件:
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.get(id=pk)
form=TaskForm(instance=task)
if request.method=='POST':
form = TaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'tasks/update_task.html',context=context)
<br />
修改功能实现
# 删除功能
开始删除功能
# 新建 html
创建删除模板
<p>Are you sure want to delete "{{item}}" ?</p>
<a href="`{% url 'tasks:list'%}`">Cancel</a>
# 修改 views
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
#Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.get(id=pk)
form=TaskForm(instance=task)
if request.method=='POST':
form = TaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'tasks/update_task.html',context=context)
def deleteTask(request,pk):
return render(request,'tasks/delete.html')
# 修改 url 文件
from django.urls import path
from . import views
app_name = 'tasks'
urlpatterns = [
path('', views.index, name='list'),
path('update_task/<str:pk>',views.updateTask,name='update_task'),
path('delete/<str:pk>', views.deleteTask, name='delete_task'),
]
# 再次修改 view 文件
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.get(id=pk)
form=TaskForm(instance=task)
if request.method=='POST':
form = TaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'tasks/update_task.html',context=context)
def deleteTask(request,pk):
item=Task.objects.get(id=pk)
context={'item':item}
return render(request,'tasks/delete.html',context)<br />
# 查看页面
<br />
# 修改 html 删除页面
<p>Are you sure want to delete "{{item}}" ?</p>
<a href="`{% url 'tasks:list' %}`">Cancel</a>
<form method="POST" action="">
<input type="submit" name="Confirm">
</form>
<br />
页面展示
# 修改 views 文件
from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import *
from .forms import *
# Create your views here.
def index(request):
tasks=Task.objects.all()
form=TaskForm()
if request.method=='POST':
form=TaskForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'tasks':tasks,'form':form}
return render(request,'tasks/list.html',context)
def updateTask(request,pk):
task=Task.objects.get(id=pk)
form=TaskForm(instance=task)
if request.method=='POST':
form = TaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'tasks/update_task.html',context=context)
def deleteTask(request,pk):
item=Task.objects.get(id=pk)
if request.method=='POST':
item.delete()
return redirect('/')
context={'item':item}
return render(request,'tasks/delete.html',context=context)
页面展示可以成功删除:
# 修改一下 list 的 html 页面:
<h3>TO DO</h3>
<form method="POST" action="/">
{{form}}
<input type="submit" name="create Task">
</form>
`{% for task in tasks %}`
`{% endfor %}`
# 完成的项目
<br />
<br />
最终效果