本篇文章要点:
- 内建用户系统
- 文件上传
- django-发送邮件
- 项目部署-uWSGI
- 项目部署-nginx
1. 内建用户系统
django自带一个用户认证系统,它可以处理用户账号、组、权限以及基于cookie的用户会话。
内建模型类
引入:from django.contrib.auth.models import User
在数据库中查看内建模型类的属性Field:
模型操作
user = User.objects.create_user(username='',password=''等等)
#会自动把密码处理成哈希值等等
#创建超级用户
user = User.objects.create_superuser(username='', password=''等等)
from django.contrib.auth.models import User
#一查二改三保存
u = User.objects.get(username='用户名')
user.is_active = False
user.save()
django内置用户系统提供了密码校验的方法,不需要向传统方法转换为哈希值校验 。
from django.contrib.auth import authenticate
user = authenticate(username=username,password=password)
# 校验成功返回对应的user对象,否则返回None
#1获取user
user.set_password()
#3保存
?
from django.contrib.auth import login
def login_view(request):
user = authenticate(username=username,password=password)
if user:
login(request, user)
#else:跳转到settings.py中LOFIN_URL = '/login'
此方法只会存取session,而且存活时间不可控
from django.contrib.auth.decorators import login_required
@login_required
def index_view(request):#登录状态下访问视图
#当前登录用户获取
login_user = request.user
from django.contrib.auth import logout
def logout_view(request):
logout(request)
tip:?next=/index 在登录完成后可以设计返回原来的页面
如何扩建你内建用户表字段?
建立新表,跟表做1对1。
继承内建的抽象user模型类:把内建表的模型类粘贴到自己模型层中,不让内建模型层初始化;
注意 此方案必须在数据库迁移之前就定义好所有的表字段。
- 添加新的应用
- 定义模型类继承AbstractUser
- setting.py中AUTH_USRE_MODEL ='应用名.类名' (此操作必须在第一次migrate之前进行)
2. 文件上传
应用场景
- 上传头像
- 上传流程性的文档[pdf,txt等]
文件上传的规则
上传规则-前端 [HTML]
- 文件上传必须为post提交方式
- <form>中必须有enctype="multipart/form-data"才会包含文件内容数据
- 表单中用<input type="file" name="xxx">标签上传文件(新的表单控件)
上传规则-后端
- 视图函数中,用request.FILES取文件框的内容
- file=request.FILES["xxx"]? #获取文件对象
- 属性:file.name文件名; file.file文件的字节流数据
相关配置
1.创建与manage.py文件同级目录文件夹media
2.配置文件的访问路径和储存路径
#settings.py
MEDIA_URL = '/media/',
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
3.需要手动绑定:主路由添加路由
#自定义静态路由
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
如何保存用户上传的文件?
def upload_view(request):
if request.method == "GET":
return render(request, 'test_upload.html')
elif request.method == "POST":
a_file = request.FILES['myfile']
print('上传的文件名是:', a_file.name)
filename = os.path.join(settings.MEDIA_ROOT, a_file.name)
with open(filename, 'wb') as f:
data = a_file.file.read()
f.write(data)
return HttpResponse('接收文件:' + a_file.name +"成功")
缺点:用户上传文件重名问题不好解决。
#借助ORM
#字段 FileField(upload='子目录名')
def upload_view(request):
if request.method == "GET":
return render(request, 'test_upload.html')
elif request.method == 'POST':
title = request.POST['title']
myfile = request.FILES['myfile']
#模型类Content
Content.objects.create(title=title, picture=myfile)
return HttpResponse('---upload is ok---')
django会自动处理重命名,把后面重名文件名修改;
3. django发送邮件
业务场景
邮件相关协议
SMTP 简单邮件传输协议 | IMAP 交互式邮件访问协议 | POP3邮局协议(第三版本) |
---|
属于'推送'协议 | 属于‘拉取’协议 从本地邮件客户端访问远程服务器 | 属于‘拉取’协议 | 用来发送邮件 | IMAP具备摘要浏览功能,可预览部分摘要,再下载整个邮件,为双向协议. | POP3必须下载全部邮件(稍慢),无摘要功能为单向协议。 |
图中为用户A向用户B发送邮件的过程:
邮件相关配置
django配置邮件功能主要为SMTP协议负责发送邮件
1. 给django授权一个邮箱
- 申请QQ邮箱或其他邮箱,在账号里面开启pop3\SMTP服务,拿到授权码
- 然后再settings.py中配置,如下:
# 邮件相关配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = 'XXX@qq.com'
EMAIL_HOST_PASSWORD = '********' #第三方登录邮箱的授权码
EMAIL_USE_TLS = False #与stmp服务器通信时,是否启动TLS连接(安全连接)默认False 加密过程复杂度过高,免费用户一般不会给发送TLS
2. 函数调用
按照如下格式发送邮件:
#python3 manage.py shell
from django.core import mail
mail.send_mail(
subject=,#题目
message=,#消息内容
from_email=,#发送者[当前配置邮箱]
recipient_list=['xxx@qq.com'],#接受者邮箱列表
)
案例
需求:用中间件实现抓取视图函数的异常,并以邮件的形式将异常信息发送给指定联系人
class ExceptionMW(MiddlewareMixin):
def process_exception(self, request, exception):
print(traceback.format_exc)
mail.send_mail(subject='mysite1报错了··',message=traceback.format_exc(), from_email='xxx@qq.com',
recipient_list=settings.EX_EMAIL)
return HttpResponse('---sorry,当前网页有点忙')
4. 项目配置-uWSGI
????????runserver中有健全的网络IO模型,django本身不认识http请求和响应,runserver把http封装给WSGI规范和要求给django,而django会根据WSGI规范来处理;之后使用uwsgi来代替,性能更高。
什么是uWSGI?
????????WSGI定义-Web服务器网管接口,开发结束后,完善的项目代码需要在一个高效稳定的环境中运行,这时候可以使用WSGI;而uWSGI是WSGI的一种,他可以实现http协议,WSGI协议,和uwsgi协议等等。
配置uWSGI
0. 安装sudo pip3 install uwsgi
1. 添加配置文件:项目同名文件夹/uwsgi.ini 如mysite1/mysite1/uwsgi.ini
2. 文件以[uwsgi]开头,有如下配置项:
socket = 127.0.0.1:8000 #嵌套字方式[需要有提前配置nginx]
http = ... #http方式
chdir = /home/../my_project #项目当前工作目录
wsgi-file = my_project/wsgi.py #项目中wsgi.py文件的位置,相对与当前工作目录
process =4 #进程个数
threads = 2 #每个进程的线程个数
pidfile = uwgi.pid #服务的pid记录文件
daemonize = uwsgi.log #服务的目录文件位置
master= True #开启主进程管理模式
3. django的settings需要配置:
- 修改settings.py 将DEBUG=False
- ALLOWED_HOSTS = ['网站域名']或者['服务监听的ip地址']
uWSGI的运行管理
启动uwsgi
uwsgi--ini uwsgi.ini (cd到所在目录下)
停止uwsgi
uwsgi --stop uwsgi.pid (cd到所在目录下)
注意:每次启动或者停止uwsgi时需要用 命令 :ps aux|grep 'uwsgi' 确认结果是否符合预期
?????????? django中代码有任何修改,需要重启uwsgi
常见错误
- 启动失败:端口被占用
- 重复启动,kill进程,如下:?
#terminal
cat uwsgi.pid #查看进程号
ps aux|grep 'uwsgi'
sudo kill -9 进程号 #杀死进程(强制终止)
5. Nginx
????????Nginx是轻量级的高性能Web服务器,提供诸如HTTP代理和反向代理、负载均衡等一系列重要特性,它是由c语言编写,执行效率高。
用处:浏览器发过来的请求全部给nginx,由nginx进行分发请求(反向代理),转发策略(负载均衡)
如何安装nginx
- sudo apt install nginx
- nginx -v 查看版本
- 安装成功会强行霸占80端口(直接输入127.0.0.1默认进入80端口),如下:
配置nginx
1. sudo vim /etc/nginx/sites-enabled/default
2. 进入文件后只需修改location项
3. 通过sudo nginx -t 检查是否有错误
使用方法
sudo /etc/init.d/start|stop|restart|status
sudo service nginx start|stop|restart|status
nginx配置修改时,必须重新启动,否则配置不生效
常见问题
- 502响应,代表nginx反向代理配置成功,但对应的uWSGI未启动;
- 404响应,路由不在django配置中;nginx配置错误,未禁止掉try_files;
5. 静态文件配置
配置好nginx后,它是不会处理静态文件的,需要手动配置,具体方法如下。
- 创建新路径- 存放django中所有静态文件 如/home/arlikache/项目名_static/
- 添加配置- STATIC_ROOT = '/home/arlikache/项目名_static/static'
- 进入项目,执行python3 manage.py collectstatic 后,所有静态文件复制到static_root中,包括django内置静态资源
- nginx配置中添加新配置,如下:
404和500页面配置
????????在模版文件夹中添加404.html模版,视图触发Http404异常时自动被显示(前提DEBUG=False),500同理。
过滤敏感信息
??????? 上面的邮件发送案例中,报错邮件会显示一些错误的追踪,这些错误追踪会出现如password等敏感信息,django自己提供了两种信息的过滤。
- 局部变量
- POST提交数据
from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
# 局部变量
@sensitives_variables('user','pw') #注意若不传参,会过滤所有的局部变量。
def process_info(user):
pw = user.password
name = user.name
#post提交数据
@sensitive_post_parameters
def index(request):
s =request.POST['username'] = request.POST['abcd']
配置流程总结
- 购买公有云,通过ssh登录系统
- 在安装机器上安装和配置同版本的环境[py,数据库等]
- django项目迁移--sudo scp 复制文件夹路径 root@IP地址: /home/root/xxx
- 用uWSGI代替python3 manage.py runserver 方法启动服务器
- 配置nginx反向代理服务器
- 用nginx配置静态文件路径,解决静态路径问题
?
至此,django系列的基础部分终于完成了!!
课程地址:2021最新版Django全套视频(django框架快速上手)_Python全栈_哔哩哔哩_bilibili
|