项目结构 创建项目文件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 可以列出所有指令
- wsgi.py: WEB服务网关的配置文件-Django正式启动时,用到的
- urls.py 项目的主路由配置, 处理htpp请求
- 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自定义配置
- 个性化的配置全局变量,防止覆盖共有配置
URL urls.py引入方式 from django.conf import settings
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="这是第一个页面" return HttpResponse(html)路由配置
- path() 函数
- 导入 - from django.urls import path
- 语法 - path(route,views,name=None)
- 参数:
- route: 字符串类型,匹配请求路径
- views: 指定视图处理函数的名称
- name: 为地址起别名,在模板中地址反向解析时使用
- 语法: <转换器类型:自定义名>
- 作用: 若转换器类型匹配到对应的数据,则将数据按照关键字传参的方式传递给视图函数
- 例子: path(‘page/int:page’,views.xxx)
- 其中这个int型的page传递到这个views数据里面(page=x)
- 转换器类型
str: int slug(ASCLL字母或者数字以及字符和下划线组成的短标签) path(匹配非空字段,包括分隔符)
语法: re_path(reg,view,name=‘xxx’)
传参: "(?Ppattern)"匹配语法规则看例
例子:
请求和响应 请求方法re_path(r’^other/(?Pd(1,2))/(?Pw(1,2))/(?Pd(1,2))$',view) # 一到两位加减法
get: 获得页面信息,返回实体
head:类似get,但是返回只有响应头
post:提交表单用的
put: 更新数据
delete: 删除指定页面
connect: 代理服务器
options: 运行客户端查看服务器端性能
trace: 回显服务器收到的请求,用于诊断和测试
- 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: 内部服务器错误
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
- 创建模板文件夹<项目名>/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)
加载简单的模板变量{{ name }}{{ key }}
可以传递的内容: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%}
-
- 绝对地址
- 相对地址/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
- 安装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: 后台显示字段名方式,默认显示类属性名,可以设置
在模型类里面在添加类
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对象:
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之前进行
- 前端
- 后端
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 是单向, 服务器都不知道, 速度慢一点, 没有摘要浏览作用
- 邮箱授权
去相应的邮箱获取授权码 - 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 -
查看占用的端口号进程
nginx部署sudo lsof -i:端口号 查询出具体进程;
sudo kill -9 [id]杀掉进程后在启动
轻量级高性能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'] #...