安装
sudo pip3 install django==2.2.12
项目结构
创建项目文件
django-admin startproject config . # 创建一个config配置文件和managelpy
启动端口
python manage.py runserver [可选: 端口号]
上面的方法开启了一个开发版的server
关闭服务
直接在服务终端下Ctrl+c关闭服务
在其他终端(开了好几个终端)
执行sudo lsof -i:8000 查询Django的进程id
执行kill -9 对于Django进程id关闭
查看manage.py指令
- python3 manage.py runseever 启动服务
- python3 manage.py startapp 创建应用
- python3 manage.py migrate 数据库迁移(更新数据库)
- …
- 执行python3 manage.py 可以列出所有指令
config配置文件夹里面的文件
- wsgi.py: WEB服务网关的配置文件-Django正式启动时,用到的
- urls.py 项目的主路由配置, 处理htpp请求
- settings.py 项目配置文件,用来启用项目配置等
settings.py 配置项
- 包含 共有配置 和 自定义配置
- 配置项格式例: BASE_DIR = “xxxx”(大写的全局变量名=值(自定义对象,字符串什么都可以))
- 打开项目文件夹在pycharm里面一定顶层是你打开的服务位置
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-(0_!sv8oe#thau5k74!9+zz_@)a2%bm3)vev+zq2%9x6x@4-ah'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# 启动模式
# True - 调试模式
## 1. 代码改动后立刻重启服务
## 2. 报错页面
# False - 正式启动模式/上线模式
# ALLOWED_HOSTS 请求host头,默认是本机127.0.0.1。 针对不同的域名开设请求 '*'表示所有网卡
ALLOWED_HOSTS = []
## 公有配置,内网链接
# python3 manage.py runseerver 0.0.0.0:5000 # 127表示本机,0表示内网所有主机
# 指定网络设备如果内网环境下其他主机想正常访问该站点,需要加ALLOWED_HOSTS=['内网ip']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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 = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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 = 'config.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/
# 语言信息,管理后台 中文表示 zh-Hans
LANGUAGE_CODE = 'en-us'
# 时区 Asia/Shanghai 亚洲上海,默认也是北京时间
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'
settings.py自定义配置
- 个性化的配置全局变量,防止覆盖共有配置
引入方式 from django.conf import settings
URL
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('admin/',admin.site.urls), # 自带的管理后台
path('page/2003/',views.page_2003)
#path('url位置',函数导入)
]
views视图函数
- 语法
# 函数
#def xxx(request[,其他参数..]):
# return HttpResponse对象
from django.http import HttpResponse
def test(requets):
html="<h1>这是第一个页面</h1>"
return HttpResponse(html)
路由配置
- path() 函数
- 导入 - from django.urls import path
- 语法 - path(route,views,name=None)
- 参数:
- route: 字符串类型,匹配请求路径
- views: 指定视图处理函数的名称
- name: 为地址起别名,在模板中地址反向解析时使用
path转换器
- 语法: <转换器类型:自定义名>
- 作用: 若转换器类型匹配到对应的数据,则将数据按照关键字传参的方式传递给视图函数
- 例子: path(‘page/int:page’,views.xxx)
- 其中这个int型的page传递到这个views数据里面(page=x)
- 转换器类型
str: int slug(ASCLL字母或者数字以及字符和下划线组成的短标签) path(匹配非空字段,包括分隔符)
re_path转换器
语法: re_path(reg,view,name=‘xxx’)
传参: "(?Ppattern)"匹配语法规则看例
例子:
re_path(r’^other/(?P\d(1,2))/(?P\w(1,2))/(?P\d(1,2))$',view) # 一到两位加减法
请求和响应
请求方法
get: 获得页面信息,返回实体
head:类似get,但是返回只有响应头
post:提交表单用的
put: 更新数据
delete: 删除指定页面
connect: 代理服务器
options: 运行客户端查看服务器端性能
trace: 回显服务器收到的请求,用于诊断和测试
Django里面的请求
- path_info:URL字符串
- method: 字符串,表示http请求的方法
- GET: QueryDict 查询字典对象,包含get请求方法的所有数据
- POST: QueryDict 查询字典对象,包含post请求方法的所有数据
- FILES: 类似字典对象,包含文件上传信息
- COOKIES: Python字典,包含所有cookie,键和值都为字符串
- session: 类似字典,表示当前会话
- body: 字符串,请求体的内容(POST和PUT)
- scheme: 请求协议('http/https)
- request.get_full_path(): 完整路径
- request.META: 请求中的元数据(消息头)
-request.META[‘REMOTE_ADDR’]:客户端IP地址
相应状态码
- 200:请求成功
- 301: 永久重定向-资源(网页)
- 302: 临时重定向
- 404: 请求资源(网页等)不存在
- 500: 内部服务器错误
django相应对象
HttpResponse(content=相应体,content-type=响应体数据类型,status=状态码)
- content-typt:
- ‘text/html’(默认,html对象)
- ‘text/plain’(纯文本)
- ‘text/css’(css文件)
- ‘text/javascript’(js文件)
- ‘multipart/form-data’(文件提交)
- ‘application/json’(json传输)
- ‘application/xml’(xml文件)
- HttpResponse子类
- HttpResponseRedirect 重定向 302
- HttpResponseNotModified 未修改 304
- HttpResponseBadRequest 错误请求 400
- HttpResponseNotFound 没有对应资源 404
- HttpResponseForbidden 请求被禁止 403
- HttpResponseServerError 服务器错误 500
django的设计模式和模板层
模板配置
- 创建模板文件夹<项目名>/templates
- 在settings.py 中的TEMPLATES配置项配置
- BACKEND:指定模板引擎
- DIRS:模板搜索目录(“一个或多个”)
- APP_DIRS: 是否要在应用中的templates文件夹中搜索
- OPTIONS: 有关模板的选项
- 要修改的部分: 设置DIRS: [os.path.join(BASE_DIR,‘templates’)]
模板加载方式
- 视图中写如下
from django.template import loader
# 1. 通过loader加载模板
t = loader.get_template('模板名')
# 2. 将t 转换成html字符串
html = t.reader(字典数据)
# 3. 用响应对象将转换的字符串返回给浏览器
# return HttpRespondse(html)
方法二
from django.shortcuts import render
# return render(request,'模板名',字典数据)
模板传递字典
# 模板加载方便方法
def test_html2(requst):
from django.shortcuts import render
dic = {
'name':'微信',
'key':'我喜欢'
}
return render(requst,'test_html2.html',dic)
<body>
加载简单的
<div>{{ name }}</div>
<div>{{ key }}</div>
</body>
模板变量
可以传递的内容:str,int,list,tuple,dict,func,obj
- 使用方法
- {{ 变量名 }}
- {{ 变量名.index}}
- {{ 变量名.key}}
- {{ 对象.方法 }}
- {{ 函数名 }}
标签(这些东西可以在前端实现)
{% 标签 %}
...
{%结束标签%}
if 标签
{% if 条件表达式1%}
...
{% elif 条件表达式2 %}
...
{% else 条件表达式3 %}
...
{% endif %}
for 标签
{% for 变量 in 可迭代对象%}
... 循环语句
{% empty %}
... 可迭代对象无数据时填充语句
{% endfor %}
for 标签的属性
forloop.counter: 从1开始的索引(索引自动+1)
forloop.conter0: 从0开始的索引
forloop.revcounter: 倒序索引
forloop.revcounter0: 索引倒叙
forloop.first 第一次通过循环则为真
forloop.last 最后一次为真
forloop.parentloop 当嵌套循环,parentloop表示外层循环
过滤器和继承
语法 {{变量1|过滤器:‘参数值1’ | 过滤器2:‘参数值2’ …}}
常见过滤器
- lower 大写变小写
- upper 大写
- safe 不进行html转义,绝对安全的数据
- add: 'n' 将value增加n
- truncatechars:'n', 字符串长度超过n用("...")代替
-
继承
-
子模板继承父模板方法{% extends ‘base.html’ %}
修改的模块{%block block_name%} 字模板修改 {%endblock block_name%}
-
父模板
-
内容块: 可以让子模板修改的块
{%block block_name%} 字模板修改 {%endblock block_name%}
-
url反向解析
- 绝对地址
- 相对地址/page/3 = http://127.0.0.1:8000/page/3开头要加/
path的别名使用 - path中
path(‘page’,views.page_url,name=‘page_url’)
- 模板中
{% url ‘page_url’ %} = 127:8000/page
{% url ‘pape_url’ age=‘18’ name=‘ff’ %} = 127:8000/page?age=18&name=ff
- 视图中
from django.urls import reverse
reverse('别名',args=[],kwargs={})
ex:
print(reverse('pagen',args=[300])) # 填充path转换器
print(reversed('person',kwarges={'name':'xixi','age':18})) # 填充参数
静态文件
不走视图的文件
- 配置setting.py
首先配置静态文件的url路径
语法: 在setting.py末尾添加 STATIC_URL=‘/static’
说明: 配置之后就可以通过base_url/static/xxx去访问文件了
然后配置静态文件的实际路径
配置: STATICFILES_DIRS=(os.path.json(BASEDIR,‘static’),)
- 模板中使用
- 加载,static-{%load static%}
- 使用: {% static ‘静态资源路径’ %}
- 样例:
应用及分布式路由
##应用
- 使用如下命令创建文件夹
python manage.py startapp music
- 在setting.py里面配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
- 创建的app文件夹相关文件解析
- migrations文件夹: 配置数据库
- admin.py 默认管理后台
- apps.py 相关配置
- models.py 模型层入口,与数据库相关
- tests.py 测试入口
- views 视图函数
分布式路由
- 主路由
urls里面加入
from djiango.urls import path,include
path(‘url’,include(‘music.urls’)) # 交给music.urls里面的文件去处理
- 子路由
from django.urls import path
import views
# 必须用这个命名
urlpatterns = [
'''相关路由'''
]
app下的模板层
步骤
- 应用下创建templates文件夹
- settings里面的’APP_DIRS’值为true即可(内外同名外层优先,应用安装应用创建顺序)
- 解决同名方法,在templates里面创建文件夹,文件夹内部在放置html
通用解决策略,统一放在最外层的templates管理,在最外层建立app同名文件夹管理html
模型层及ORM
django配置mysql
- 安装mysqlclient
- sudo apt-get install python3-dev default-libmysqlclient-dev
- sudo pip install mysqlclient
- 创建数据库
mysql -uroot -p 进入mysql
create database 数据库名 default charset utf8- 通常数据库名和项目名保持一致
- settings.py 里面配置数据库
修改 DATABASES配置内容, sqlite3 变为 mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysite3',
'USER': 'root',
'PASSWORD':'tarena',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
ORM
- 在models.py里面啊写你的类
from django.db import models
class book(models.Model): # 继承之后就可以使用
title = models.CharField('书名',max_length=50) # 最大长度
price = models.DecimalField("定价",max_digits=7,decimal_places=2,default=0.0) # 最长的字符长度,小数点位置,默认值
- 执行同步命令同步表到mysql
python3 manage.py makemigrations # 在应用下models.py文件生成中间文件,并保存在migrations文件夹中(生成迁移文件)
python3 manage.py migrate # 执行迁移脚本
- 字段类型
from django.db import models
models.BooleanField() # 数据库类型为tinyint(1) 1,0
models.CharField() # varchar 必须包含参数max_length
models.DateField()
# 类型:data
# 参数(3选一):
# auto_now:(True,False),保存对象时更新时间
# auto_now_add: (True,False), 第一次创建更新时间
# default: 设置当前时间
models.DateTimeField()# 参数跟上面一样,更常用
models.FloatField() # double类型
models.DecimalField()
# decimal类型
# max_digits: 位数总数,包括小数点后的数
# dicimal_places: 小数点是几位
models.EmailField()
# varchar类型
# 自带email正则
models.IntegerField()
# int类型
models.ImageField()
# varchar(100)类型
# 保存图片路径
models.TextField()
# longText类型,不限长度
字段选项-额外信息
- 格式: models.xxxField(字段选项…)
- 类型
- primary_key: (主键) # 默认主键为id,送的主键,指定之后就不创建id
- blank: 设置为True时,字段可以为空,False必须填写。在控制后台进行控制的
- null: 设置为Ture时, 在数据表中可以为空(建议不要使用,用default=‘’)
- default: 默认值,最好加入,在null=Flase时就加上吧
- db_index: True表示增加索引
- unique: True 表示索引唯一
- db_column: 指定字段名(默认类名)
- verbose_name: 后台显示字段名方式,默认显示类属性名,可以设置
模型类-Meta类
在模型类里面在添加类
from django.db import models
class book(models.Model):
class Meta:
db_table = "book" # 修改当前表名为book
管理器对象(增删改查)
Mymodel.objects # 里面有一些常用的方
- 增,创建数据
from bookstore.models import book
- Mymodel.objects.create(属性1=值1,属性2=值2…) # 成功返回创建好的实体对象,失败抛出异常
- obj = Mymodel(属性=值,属性=值) obj.属性 = 值 obj.save()保存
- 查找
# 查询整体数据
Mymodel.objects.all() #查询全部记录,返回QuerySet查询对象
## 循环遍历一整个表,返回一个数组,使用对象的方法得到数据,即book.title
Mymodel.objects.values('列1','列2',...) # 查询部分列的数据并返回
# 返回{"列1":"值"...},获取数据用book['title']
order_by('列名1','-列名2') # 对结果进行排序返回,默认升序,倒叙的话前面加-
# 条件查询
get(条件) # 查询单独一条符合条件的记录
# 直接返回一条数据的对象,如果查询到的数据大于一条,报错,如果没有查询到,报错。
filter(属性1=值,属性2=值) # 查询符合条件的多条记录
# 多个参数表示and,按照值进行查询
exclude(条件) # 查询符合条件外的记录
# 非等值查询
## 查询谓词
id__gt # 大于指定值
id__gte # 大于等于
id__lt # 小于
id__lte # 小于等于
id__contains # 包含指定值
id__startwith # 以某某开始 id__endwith 以某某结束
id__in # 在一个列表里面['条件1','条件2'...]
id__range # 在某个区间内(start,end),例:(5,10)
修改操作
- 单个更新
- 使用查询中get方法得到对象
- 直接使用.方法修改里面的值
- 对象.save()保存
- 多个更新
# 实例1:将id>3的价格改成0
books = Book.objects.filter(id_gt=3)
books.updata(price=0)
# 实例二: 所有书的售价定位100
books = Book.objects.all()
books.updata(price=100)
删除
- 步骤
- 查找数据
- 调用.delete()方法直接删除,注意防止错误加try
- 伪删除
一般的数据都是比较重要的,是不会直接删除的,所以一般都会在表里面加一个is_active字段,表示是否是删除状态,如果是,就代表删除
F对象和Q对象
F对象:
from django.db.models import F
# 例子1 将所有书的零售价涨价10元
Book.objects.all().updata(market_price=F('market_price')+10)
Q对象: 用来进行或和非操作
# 例如
Book.objects.filter(Q(price_lt=200)|Q(pub="清华大学出版社"))
# | 或运算; & 且运算; ~非运算
cookie and session
cookie
- create a cookie
HttpResponse.set_cookie(key,value=‘’,max_age=None,expire=None)
- key:cookie的名字
- value: cookie的值
- max_age: 存活时间
- expires: 具体过期的日期
- 不指定max_age和expires时 关闭浏览器失效
缓存
在内存中存入数据,能够更快的进行数据的增删改查
中间件
- 在配置目录同级的文件下创建一个中间件Middleware的包
2.创建一个python文件
# 继承这个MiddlewareMixin
from django.utiles.deprecation import MiddlewareMixin
class MyMW(MiddlewareMixin):
# 请求中间件,在请求来了之后进入,进入主路由之前调用
def process_request(self,request):
# 进入下一步返回None,否则返回HTTP请求
return None
# 进入视图之前调用
def process_view(self,request,callback,callback_args,callback_kwargs):
# 下一步表示None,否则返回HTTP请求
# callback: 路由对应的视图函数
# callback_args: 视图参数位置传参
# callback_kwargs:关键字传参
return None
# 返回之前调用
def process_responese(self,request,response):
return None
# 抛出异常调用
def process_exception(self,request,exception):
return None
- 注册中间件
在settings.py里面的MIDDLEWARE里面注册
MIDDLEWARE = [
'包名.文件'
]
CSRF 攻击
跨站伪造请求攻击
-
页面中关闭CSRF攻击
在模板中添加**{% csrf_token %}**就可以了 -
局部关闭一个csrf的views
# 引入
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt # 映入这个装饰器在视图上
def my_view(request):
return #...
内置用户系统
# 模型类位置
from django.contrib.auth.models import User
- 字段
username: 用户名
password: 密码
email: 邮箱
first_name: 名
last_name: 姓
is_supperuser: 是否管理员
is_staff: 是否可以访问is_staff
is_active:是否活跃用户,默认为true,一般不删除用户,而是吧用户设置为False
last_login: 上一次登录时间
data_joined: 用户创建时间
- 创建用户
from django.contrib.auth.models import User
user = User.objects.create_user(username="用户名",password='秘密',email='邮箱') # 创建常规用户
super_user = User.objects.create_superuser(username='用户名',password='密码',email='邮箱')
- 删除用户(伪删除)
from django.contrib.auth.models import User
try:
user = User.objects.get(username='用户名')
user.is_active = False # 记当前用户无效
user.save()
pirnt('删除成功')
except:
print('失败')
- 验证密码
from django.contrib.auth import authenticate
user = authenticate(username=username,password=password)
# 成功返回对应user对象,失败返回null
- 修改密码
from django.contrib.auth import authenticate
try:
user = User.objects.get(username=username)
uses.set_password('333')
user.save()
print('修改成功')
except:
print("修改失败")
- 登录验证登出
from django.contrib.auth import login
# 登录
def login_view(request,user):
login(request,user)
# 验证
@login_required # 配置文件配置settings.LOGIN_URL = 'xxx' 没有登录跳转到这个路由
def index_view(request):
# 该视图必须为用户登录状态下放分
# 获取当前登录用户用request.user获取
login_user = request.user
# 登出
from django.contrib.auth import logout
def logout_view(request):
logout(request)# 直接删除session
- 扩展user表
- 添加新的应用
- 定义模型类继承AbstractUser
- settings.py 指明 AUTH_USER_MODEL = ‘应用名.类名’ # 此操作在migrate之前进行
文件上传
- 前端
<form action="xxx" methed="post" enctype="multipart/form-data">
<input type="file" name="xxx"> # 上传文件
</form>
- 后端
file = request.FILES['xxx']
# FILES里面的key对于input里面的name
# file绑定文件流对象
# file.name 文件名
# file.file 文件字节流数据
- setings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,"media")
- 主路由绑定
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
- open方法
# .FILES拿到文件
file = request.FILES('name')
file_name = file.name
with open('xxx.xxx','wb') as f:
file_s = file.file.read()
f.write(file_s)
- ORM方法
# 添加一个字段
# FileField(upload='子目录名字')
file = requests.FILES['name']
content.objects.create(desc=title,myfile=file)
发送邮件
邮件相关协议
- SMTP 简单邮件发送协议(:25)
- IMAP 收邮件协议,在服务器拿到邮件(:143)
- POP3 收邮件协议TCP/IP(:110)
POP3 和 IMAP 的区别
IMAP 是双向协议,可以给服务器反馈,并且有摘要浏览作用
POP3 是单向, 服务器都不知道, 速度慢一点, 没有摘要浏览作用
django 发邮件
- 邮箱授权
去相应的邮箱获取授权码 - settings.py做相应配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 邮件引起
Email_HOST = 'smtp.qq.com' # 腾讯qq邮箱 SMTP 服务器地址 # 基本都是这个地址 比如网易 smtp.163.com
EMAIL_PORT = 25 # SMTP 服务的端口号
EMAIL_HOST_USER = 'xxx@qq.com' # 发送邮件的邮箱账号
EMAIL_HOST_PASSWORD = 'xxxx' # 邮箱授权码
EMAIL_USE_TLS = False # 与SMTP服务器通信时,是否启动TLS链接(安全链接HTTPS,免费邮箱一般是不会加密的) 默认为False
- 函数调用
from django.core import mail
# 引入配置文件
from django.conf import settings
mail.send_mail(
subject='题目',
message='消息内容',
from_email='发送者', # 当前配置邮箱
recipient_list=['xxx@qq.com'], # 接受者列表
)
- 利用中间件捕捉信息并邮件发送
mymiddleware.py里面
class ExceptionMW(MiddlewareMixin):
# 捕获异常
def process_exception(self,request,exception):
print(exception) # 直接打印异常
# 导入异常追溯
import traceback
print(traceback.format_exc())
return HttpResponse("对不起,当前网页有点忙")
项目部署
uwsgi
- uwsgi 替代 django uwsgi
- 配置nginx 反向代理服务器
- nginx 静态文件处理
uwsgi:
wsgi: Web服务器网关接口。 将http请求和响应翻译成wsgi
uWSGI: 实现了http协议的识别,还有自己的uwsgi协议。因此认识大量的协议
安装: sudo pip3 install uwsgi==2.0.18 -i https://pypi.tuna.tsinghua.edu.cn/simple/
检查: sudo pip3 freeze|grep -i ‘uwsgi’
- 配置:uwsgi
- 在同名文件夹里面添加配置文件: 项目同名文件夹/xxx.ini
如: mysite/mysite/uwsgi.ini # 主路由文件中
- 配置项 在uwsgi.ini中的首行添加[uwsgi]
[uwsgi]
# 套接字方式的IP地址: 端口号 [此模式需要有nginx]
socket = 127.0.0.1:8000
# Http 通信方式的IP地址:端口号
http = 127.0.0.1:8000
# 项目当前目录
chdir = /home/.../.../ # 绝对目录
# 项目中wsgi.py文件的目录,相对于当前工作目录
wsgi-file = my_project/wsgi.py # jango里面的配置文件存在这个文件
# 进程数(最多cpu核数)
process = 4
# 每个进程的线程个数(线程测试)
threads = 2
# 服务的pid记录文件,启动这个目录保存主进程的id
pidfile = uwsgi.pid
# 服务的日志文件位置 , 是否后台启动,log日志输出文件
daemonize = uwsgi.log
# 主进程管理模式: 主进程来开子进程
master = true
- settings.py 配置
- 修改DEBUG 为False
- 将ALLOWED_HOSTS=[]改为ALLOWED_HOSTS=[‘网站域名’]或者['服务监听的ip地址 ']
- 启动uwsgi
- cd 到 uWSGI配置文件所在目录
- uwsgi --ini uwsgi.ini
- 查看是否启动
- ps aux|grep ‘uwsgi’ >> 可以看到uwsgi的进程
-
停止uwsgi
uwsgi --stop uwsgi.pid -
查看占用的端口号进程
sudo lsof -i:端口号 查询出具体进程;
sudo kill -9 [id]杀掉进程后在启动
nginx部署
轻量级高性能Web服务器,C语言编写,执行效率高,有反向代理、负载均衡等一系列重要特性
-
反向代理
具有转发请求到其他机器的能力 -
负载均衡
对得到的请求均衡分配到不同的机器 -
安装
sudo apt install nginx
修改源
vim /etc/apt/sources.list
更改国内源 sudo apt-get update
安装后可以在终端中输入nginx -v 显示
- 配置
修改nginx的配置文件 /etc/nginx/sites-enabled/default
sudo vim 该文件
server{
... # 这个 / 表示 / 开头的路由
location / {
uwsgi_pass 127.0.0.1:8000; # 重定向到127.0.0.1的8000端口
include /etc/nginx/uwsgi_params; # 将所有的参数转到uwsgi下
}
...
# try_files 禁用掉
- 启动|停止|重启|状态
sudo /etc/init.d/nginx start|stop|restart|status
或者 sudo service nginx start|stop|restart|status
配置结束之后sudo nginx -t 检查配置语法是否存在问题
- 配置uWSGI
[uwsgi]
# 去掉http=
# 改为
socket = 127.0.0.1:8000
sudo uwsgi --stop uwsgi.pid 关闭
sudo uwsgi --ini uwsgi.ini 打开
- 排查
nginx配置位置
/etc/nginx/
在.conf文件里面:
Logging Settings里面有相关日志的目录
sudo su 切换到超级用户去访问
- nginx静态文件配置
- 创建静态文件夹
- Django settings.py中配置
STATIC_ROOT = ‘/home/tarena/…静态文件夹位置/static’
正式上线之后的路径
- 进入项目,执行 python3 manage.py collectstatic # 自动将静态文件福找到root里面
- Nginx配置中添加新配置
在server里面添加
location /static{
root /home/tarena/项目名..
}
-
404和500页面
在上线后调整404和500的访问页面.就是在模板里面添加404.html页面 -
django报错邮件
settings.py中,在基础邮箱授权后 添加如下配置:
DEBUG = False
# 错误报告接受方
ADMINS = [('name','xxx@qq.com'),('name2','xxx@qq.com')]
# 发送报错方 默认root@localhost账户,多少服务器拒绝
SERVER_EMAIL = 'email配置中的邮箱'
过滤敏感信息,视图里面添加
from django.views.decorators.debug import sensitive_variables
# 最上面装饰器
@sensitive_variables('user','pw','cc')
def process_info(user):
pw = user.pass_word
cc = user.credit_card_number
name = uesr.name
#...
POST数据过滤
from django.views.decorators.debug import sensitive_post_parameters
# 最上面装饰器
@sensitive_post_parameters('user','pw','cc')
def process_info(user):
s = request.POST['user'] + request.POST['user']
#...