Django学习笔记7

七、进阶知识(二)

7.1 内建用户系统

定义

  • Django带有一个用户认证系统。它处理用户账号、组权限及基于cookie的用户会话
  • 用户可以直接使用Django自带的用户表
  • 官方文档:https://docs.djangoproject.com/en/2.2/topics/auth

基本字段

模型类位置 from django.contrib.auth.models import User

字段含义
username用户名
password密码
email邮箱
first_name
last_name
is_superuser是否是管理员账号(/admin)
is_staff是否可以访问admin管理界面
is_active是否是活跃用户,默认为True。一般不删除用户,而是将用户的is_active设为False
last_login上一次的登录时间
date_joined用户创建的时间

创建用户

  1. 创建普通用户create_user

    from django.contrib.auth.models import User
    user = User.objects.create_user(username='用户名',password='密码',email='邮箱',...)
    
  2. 创建超级用户create_superuser

    from django.contrib.auth.models import User
    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()
    print("删除普通用户成功!")
except:
    print("删除普通用户失败")

校验密码

from django.contrib.auth import authenticate
user = authenticate(username=username,password=password)

说明:如果用户名密码校验成功则返回对应的user对象,否则返回None

修改密码

from django.contrib.auth.models import User
try:
    user = User.objects.get(username='xiaonao')
    user.set_password('654321')
    user.save()
    return HttpResponse("修改密码成功!")
except:
    return HttpResponse("修改密码失败!")

登陆状态保持

from django.contrib.auth import login
def login_view(request):
    user = authenticate(username=username, password=password)
    login(request, user)

登陆状态校验

from django.contrib.auth.decorators import login_required
@login_required
def index_view(request):
    #该视图必须为用户登录状态下可以访问
    #当前登录用户可通过request.user获取
    login_user = request.user
    ...

登陆状态取消

from django.contrib.auth import logout
def logout_view(request):
	logout(request)

内建用户表

方案一:通过建立新表,跟内建表做1对1

方案二:继承内建抽象类

步骤:

  1. 添加新的应用

  2. 定义模型类继承AbstractUser

  3. settings.py中指明AUTH_USER_MODEL=‘应用名.类名’

    注意:此操作要在第一次Migrate之前进行

示例 - user/models.py - 添加user应用

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your model here.
class UserInfo(AbstractUser):
    phone = models.CharField(max_length=11, default='')

settings.py添加配置

AUTH_USER_MODEL = 'user.UserInfo'

添加用户

from user.models import UserInfo
UserInfo.objects.create_user(username='zc', password='123456', phone='13488871101')
7.2 文件上传
  • 定义:用户可以通过浏览器将图片等文件传至网站
  • 场景:用户上传头像、上传流程性的文档[pdf,txt等]

上传规范

文件上传必须为POST提交方式

表单<form>中文件上传时必须带有enctype="multipart/form-data"时才会包含文件内容数据

表单中用<input type=“file” name=“xxx”>标签上传文件

视图函数中,用request.FILES取文件框的内容

file = request.FILES[‘xxx’]

说明:

  1. FILES的key对应页面中file框的name值
  2. file绑定文件流对象
  3. file.name 文件名
  4. file.file 文件的字节流数据

配置文件的访问路径和存储路径

在settings.py中设置MEDIA相关配置;Django把用户上传的文件,统称为media资源

Django把用户上传的文件,统称为media资源

# file: settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

MEDIA_URL和MEDIA_ROOT需要手动绑定

步骤:主路由中添加路由

from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

说明:等价于做了MEDIA_URL开头的路由,Django接到该特征请求后去MEDIA_ROOT路径查找资源

文件写入方案1:传统的open方式

@csrf_exempt
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 + "成功")

文件写入方案1:借助ORM

字段:FileField(upload=‘子目录名’)

@csrf_exempt
def upload_view_dj(request):
    if request.method == 'GET':
        return render(request, 'test_upload.html')
    elif request.method == 'POST':
        title = request.POST['title']
        a_file = request.FILES['myfile']
        Content.objects.create(desc=title,myfile=a_file)
        return HttpResponse('----upload is ok-----')
7.3 django发送邮件

业务场景

  • 业务告警
  • 邮件验证
  • 密码找回

相关协议 - SMTP

  • SMTP全称是"Simple Mail Transfer Protocol",即简单邮件传输协议(25号端口)
  • 它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转
  • 属于推送协议

相关协议 - IMAP

  • IMAP全称是Internet Mail Access Protocol,即交互式邮件访问协议,是一个应用层协议
  • 用来从本地邮件客户端(Outlook Express、Foxmail、Mozilla Thunderbird等)访问远程服务器上的邮件
  • 属于“拉取”协议

相关协议 - POP3

  • POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口为110)
  • 本协议主要用于支持使用客户端远程管理在服务器上的电子邮件
  • 属于“拉取”协议

IMAP VS POP3

两者均为“拉取”型协议,负责从邮件服务器中下载邮件

  • IMAP具备摘要浏览功能,可预览部分摘要,再下载整个邮件
  • IMAP为双向协议,客户端操作可反馈给服务器
  • POP3必须下载全部邮件,无摘要功能
  • POP3为单向协议,客户端操作无法同步服务器

Django发邮件

  • Django中配置邮件功能,主要为SMTP协议,负责发邮件
  • 原理
    • 给Django授权一个有效
    • Django用该邮箱给对应收件人发送邮件
    • django.core.mail封装了电子邮件的自动发送SMTP协议

授权步骤

  1. 申请QQ号
  2. 用QQ号登录QQ邮箱并修改设置
    • 用申请到的QQ号和密码登陆到https://mail.qq.com/
    • 修改QQ邮箱->设置->账户->"POP3/IMAP"......服务

Django配置

EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST='smtp.qq.com' # 腾讯QQ邮箱SMTP服务器地址
EMAIL_PORT=25 # SMTP服务的端口号
EMAIL_HOST_USER='xxxx@qq.com' # 发送邮件的QQ邮箱
EMAIL_HOST_PASSWORD='******' # 在QQ邮箱->设置->账户->"POP3/IMAP......服务"里得到的在第三方登录QQ邮箱授权码
EMAIL_USE_TLS=False # 与SMTP服务器通信时,是否启动TLS链接(安全链接)默认False

函数调用

from django.core import mail
mail.send_mail(
				subject,   #题目
				message,   #消息内容
				from_email,  #发送者[当前配置邮箱]
				recipient_list=['xxxqq.com'] #接受者邮箱列表
			)

练习 - 邮件告警

用中间件实现抓取视图函数的异常,并以邮件的形式将异常信息发送给指定联系人

邮件主体:‘mysite7异常告警’

内容:自定义即可,要求带有异常信息

收件人要求可灵活配置

7.4 项目部署-uwsgi

基础概念

项目部署是指在软件开发完毕后,将开发机器上运行的软件实际安装到服务器上进行长期运行

  1. 在安装机器上安装和配置同版本的环境[py,数据库等]

  2. django项目迁移

    sudo scp /home/zc/django/mysite1 root@88.77.66.55:/home/root/xxx
    请输入root密码:
    
  3. 用uWSGI替代python3 manage.py runserver方法启动服务器

  4. 配置nginx反向代理服务器

  5. 用nginx配置静态文件路径,解决静态文件路径问题

uWSGI网关接口配置

WSGI(Web Server Gateway Interface)Web服务器网关接口,是Python应用程序或框架和Web服务器之间的一种接口,被广泛使用。

使用python manage.py runserver通常只在开发和测试环境中使用。

当开发结束后,完善的项目代码需要在一个高效稳定的环境中运行,这时可以使用WSGI

uWSGI定义

uWSGI是WSGI的一种,它实现了http协议、WSGI协议以及uwsgi协议

uWSGI功能完善,支持协议众多,在python web圈热度极高

uWSGI主要以学习配置为主

uWSGI安装

Ubuntu执行sudo pip3 install uwsgi==2.0.18

https://pypi.tuna.tsinghua.edu.cn/simple

检查是否安装成功

  • sudo pip3 freeze|grep -i ‘uwsgi’
  • 如果成功安装,则会输出uWSGI=2.0.18

配置uWSGI

添加配置文件 项目同名文件夹/uwsgi.ini

如:mysite1/mysite1/uwsgi.ini

文件以**[uwsgi]**开头,有如下配置项:

套接字方式的IP地址:端口号【此模式需要有nginx】

socket=127.0.0.1:8000

Http通信方式的IP地址:端口号

http=127.0.0.1:8000

项目当前工作目录

chdir=/home/tarena/…/my_project

项目中wsgi.py文件的目录,相对于当前工作目录

wsgi-file=my_project/wsgi.py

进程个数

process=4

每个进程的线程个数

threads=2

服务的pid记录文件

pidfile=uwsgi.pid

服务的日志文件位置

daemonize=uwsgi.log

开启主进程管理模式

master=true

特殊说明:Django的settings.py需要做如下配置

  1. 修改settings.py将DEBUG=True改为DEBUG=False
  2. 修改settings.py将ALLOWED_HOSTS=[]改为ALLOWED_HOSTS=[‘网站域名’]或者[‘服务监听的ip地址’]

启动uwsgi

cd到uWSGI配置文件所在目录

uwsgi --ini uwsgi.ini

停止uwsgi

cd到uWSGI配置文件所在目录

uwsgi --stop uwsgi.pid

uWSGI的运行说明

  1. 无论是启动还是关闭,都需要执行ps aux|grep 'uwsgi’确认是否符合预期
  2. 启动成功后,进程在后台执行,所有日志均输出在配置文件所在目录的uwsgi.log中
  3. Django中代码有任何修改,需要重新启动uwsgi

uWSGI测试

在浏览器端输入http://127.0.0.1:8000/url进行测试

注意,此时端口8000被uWSGI进程监听,并非runserver

如果当前有预期返回,则uWSGI启动成功

uWSGI常见问题汇总

  1. 启动失败:端口被占用

    原因:有其他进程占用uWSGI启动的端口

    解决方案:可执行sudo lsof -i:端口号查询出具体进程;杀掉进程后,重新启动uWSGI即可

  2. 停止失败:stop无法关闭uWSGI

    原因:重复启动uWSGI,导致pid文件中的进程号失准

    解决方案:ps出uWSGI进程,手动kill掉

7.5 项目部署-nginx

什么是Nginx

  • Nginx是轻量级的高性能Web服务器,提供了诸如HTTP代理和反向代理、负载均衡等一系列重要特性
  • C语言编写,执行效率高
  • nginx作用
    • 负载均衡,多台服务器轮流处理请求
    • 反向代理
  • 原理
    • 客户端请求nginx,再由nginx将请求转发uWSGI运行的django

安装

sudo apt install nginx

如果下载速度很慢,考虑更换为国内源

vim /etc/apt/sources.list
# 更换国内源
sudo apt-get update

安装完毕后,ubuntu终端中输入nginx -v显示如下:

nginx version: nginx/1.14.0(Ubuntu)

配置

修改nginx的配置文件/etc/nginx/sites/enabled/default

sudo vim 该文件

# 在server节点下添加新的location项,指向uwsgi的ip与端口
server {
    ...
    location / {
        uwsgi_pass 127.0.0.1:8000; #重定向到127.0.0.1的8000端口
        include /etc/nginx/uwsgi_params; #将所有的参数转到uwsgi下
    }
}

启动/停止

$ sudo /etc/init.d/nginx start|stop|restart|status

#或

$ sudo service nginx start|stop|restart|status

启动 - sudo /etc/init.d/nginx start

停止 - sudo /etc/init.d/nginx stop

重启 - sudo /etc/init.d/nginx restart

注意:nginx配置只要修改,就需要进行重启,否则配置不生效

修改uWSGI配置

说明nginx负责接收请求,并把请求转发给后面的uWSGI

此模式下,uWSGI需要以socket模式启动

样例:

[uwsgi]
# 去掉如下
# http=127.0.0.1:8000
# 改为
socket=127.0.0.1:8000

uWSGI配置变化后,也需重启

进入到 项目同名文件夹下
$ sudo uwsgi --stop uwsgi.pid
$ sudo uwsgi --ini uwsgi.ini

常见问题排查

宗旨:看日志!

nginx日志位置:

​ 异常信息 /var/log/nginx/error.log

​ 正常访问信息 /var/log/nginx/access.log

uwsgi日志位置:

​ 项目同名目录下,uwsgi.log

1, 访问127.0.0.1:80地址,502响应

​ 502响应代表nginx反向代理配置成功,但是对应的uWSGI未启动

2, 访问127.0.0.1:80/url 404响应

​ 1) 路由的确不在django配置中

​ 2) nginx配置错误,未禁止掉try_files

nginx静态文件配置

  1. 创建新路径-主要存放Django所有静态文件,如:/home/tarena/项目名_static/

  2. 在Django settings.py中添加新配置

    STATIC_ROOT = '/home/tarena/项目名_static/static'
    #注意 此配置路径为 存放所有正式环境中需要的静态文件
    
  3. 进入项目,执行python3 manage.py collectstatic命令后,Django将项目中所有静态文件复制到STATIC_ROOT中,包括Django内建的静态文件

Nginx配置中添加新配置

# file: /etc/nginx/sites-enabled/default
# 新添加location /static路由配置,重定向到指定的第一步创建的路径即可
server {
    ...
    location /static {
        # root 第一步创建文件夹的绝对路径,如:
        root /home/tarena/项目名_static;
    }
    ...
}

404/550页面

在模板文件夹内添加404.html模板,当视图出发Http404异常时将会被显示

404.html仅在发布版中(即settings.py中的DEBUG=False时)才起作用

当响应处理函数触发Http404异常时就会跳转到404界面

邮箱告警

当正式服务器上代码运行有报错时,可价格错误追溯信息发至指定邮箱

settings.py中 - 在基础邮箱授权后添加如下配置:

#关闭调试模式
DEBUG = False

#错误报告接收方
ADMINS = [('guoxiaonao', 'xxxx@example.com'),('wanglaoshi', 'xxxx@example.com')]

#发送错误报告方,默认为root@localhost账户,多数邮件服务器会拒绝
SERVER_EMAIL = 'email配置中的邮箱'

报错邮件中会显示一些错误追踪,这些错误追踪中会出现如password等敏感信息,Django已经将配置文件中的敏感信息过滤修改为多个星号,但是用户自定义的视图函数需要用户手动过滤敏感信息

可过滤如下信息:

​ 局部变量

​ POST提交数据

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 = user.name
    ...

说明:

  1. 若报错邮件中牵扯到user,pw,cc等局部变量的值时,则会将其替换成*****,而name变量显示其真实值
  2. 多个装饰器时,需要将其放在最顶部
  3. 若不传参数,则过滤所有局部变量的值
from django.views.decorators.debug import sensitive_post_parameters

@sensitive_post_parameters('password', 'username')
def index(request):
     s = request.POST['username'] + request.POST['abcd']
     #'abcd'并不存在,此时引发error
     #POST中username及password的值会被替换为******

参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
学习Django时,使用PyCharm作为开发工具可以提高效率。PyCharm是一款功能强大的Python集成开发环境,它提供了丰富的功能和工具,可以帮助开发者更好地编写和调试Django应用程序。 在学习Django的过程中,可以使用PyCharm创建Django项目,并使用其内置的Django支持功能来简化开发过程。PyCharm可以自动识别Django项目的结构,并提供代码补全、语法检查、调试等功能,帮助开发者更快地编写和调试代码。 此外,PyCharm还提供了集成的版本控制系统,如Git,可以方便地管理和追踪代码的变化。它还支持自动化测试和部署,可以帮助开发者更好地进行项目管理和发布。 总之,使用PyCharm作为开发工具可以提高Django学习的效率和便利性。它的强大功能和友好的用户界面使得开发者可以更专注于代码的编写和项目的开发。\[1\] \[2\] \[3\] #### 引用[.reference_title] - *1* *3* [PyCharm平台下初学Django框架](https://blog.csdn.net/howard2005/article/details/93491364)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [pycharm平台下的Django教程](https://blog.csdn.net/Sunshine_ZCC/article/details/73918408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值