python-django框架-电商项目-用户模块开发_20191117
实现注册的基本逻辑:
1,注册页面
- 注意:注册页面需要静态文件的支持,另外注册页面是基础基类的,
- 1,url,路由系统,
- 2,views,视图系统,还是使用类视图,里面有很多的函数,
2,views.py文件
- get函数,返回浏览器注册页面,
- post函数,
- 这个函数处理四个事情:#web开发的通用的一个流程就是这样的,
- 1,接收数据
- 2,进行数据校验:用户已存在的时候要做异常处理,注册失败的时候要做异常处理,
- 3,进行业务处理,进行用户注册,创建一条用户记录,可以使用django的认证系统,提供了一个创建用户的方法,
- user = User.objects.create_user(username, email, password)
- 4,返回应答,使用反向解析返回首页,valid:有效的 pattern:模式
######################################################################
激活邮件的设计思路
- 需求背景:
- 用户注册之后,给用户发送一个激活邮件,提示用户去打开邮件,
- 然后用户点击这个激活邮件之后激活账户,点击激活连接要跳转到登陆页面
- 如果链接过期了之后,实际应该返回一个页面,然后点击一个地方,可以再发一个激活连接,
- 代码设计,
- 发送激活邮件,包含激活链接,每一个人的都应该是不一样的,包含用户的身份信息,如何设计??
- 设计成这样一个连接,127.0.0.1:8000/user/active/1(id)
- 这样发了这个邮件,我就可以获取到最后的id,我收到了邮件,就知道你在激活,我就可以去修改数据库了,
- 但是有些人会捣乱,不停的修改id去访问,所以怎么办?就要id加密
- 加密:
- 引入一个包:from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,这个这个包加密,
- 除了加密之外,还可以设置过期时间,时间过了连接失效,就不能激活了,
- 发送邮件的配置:
- 加密是在注册的函数,解密的时候是一个单独的函数,解密函数,
问题:
- 发邮件的流程需要优化,因为这是一个阻塞型的,因为邮件没发完就要等待,用户体验不好,怎么解决?
- 异步执行任务,python中有一个celery的包,可以执行异步的执行任务,比如发送邮件,上传文件,下载文件,这种耗时的操作都可以使用celery
##################################################################
好了,task启动成功了,
哈哈,我现在已经把邮件发出去了,哈哈!!!!
总结:
这一个问题,我太痛苦了,专门系统学习了Linux,git,redis,还有各种坑,装了很多的东西,包括完整的开发环境,花费了我4天的时间,
不过总的来讲还是非常值得的,
######################################################################################################
用户登录:
login类里面,继续写post函数,
- 要做四个事情,
- 接受数据
- 校验数据
- 业务处理,登陆校验,使用django的认证系统,user = authenticate(username=username, password=password)
- 返回应答,
配置redis,作为django缓存和session存储后端,
- 如果你不做配置,session是放在数据库中,
- 但是每次都到数据库中读写,速度是比较慢的,所以不能使用默认的保存session的方式,我们要有redis数据库,
- 我们需要用到一个包,django-redis,
- 怎么使用?
- 要配置,
-
# Django的缓存配置,默认缓存是在本机内存中 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", 'LOCATION': 'redis://:###@192.168.80.129:6379/5', "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } # 配置session存储,默认的登录状态是保存在django数据库中的session表中 SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default"
- 我配置到了redis的5号数据库,
- redis-cli -h 192.168.80.129
- SELECT 5
- keys * (empty list or set)
- 然后登陆,
- 再去查看keys * 你就发现是有一个记录了,就是session记录,
抽象父模板
- 一个base.html
- 一个base_no_cart.html,
- 这两个就可以另外的页面继承了,
- 一个base_use_center.html,这个继承base.html
- 一个base_detail_list.html,这个继承base_no_cart.html,
- 然后就可以使用这四个父模板来改造我们的网页了,
- 首先改造注册和登陆的页面,改造成功,
用户中心页面显示,
- 先让用户信息的3个页面显示出来,
- 页面,url,views,三个有了, 就可以显示了,
登陆装饰器和登陆后页面跳转
- 户信息的3个页面,没有登陆是不能看到的,所以要判断,
- 使用django带的认证系统给的登陆装饰器,LoginRequired
- 目前看来,django的认证系统需要系统的学习,
- from django.contrib.auth.decorators import login_required
- 总体的实现效果:
- 如果用户没有登陆访问一个用户中心页面,会跳出去到登陆页面,后面会加上url,
- 登陆之后,会直接到用户中心页面,
- 如果直接登陆,就是到首页
- 这就是使用的django内置的登陆装饰器实现的, 所以这个要学习,
LoginRequiredMixin类的使用:
- 如果你有很多的视图都要使用登陆装饰器,可以封装一个类
- 在项目里面,一些通用的东西,我们会新建一个文件夹,utils,工具,
- 我们新建一个文件,Mixin,在这个里面新建一个类方法,LoginRequiredMixin
- 关于封装,继承,父类,这些概念的理解还不到位,
- 原理:
- 输入用户中心的地方,它调用的是url里面的对应关系,
- 然后调用的as_view,不再是原来的了,而是我们封装的,LoginRequiredMixin的as_view,做了一个包装,这个原理有时间要理清楚,
登陆后欢迎信息
- 登陆了之后,就不能再显示登陆和注册的按钮了,
- 怎么做?
- 还是django的认证系统,user.is_authenticated
- 登陆的话,request.user返回的是一个真实的user对象,否则返回的是一个anonymousUser对象
- # # 真实对象的is_authenticated方法返回的是true,匿名对象的这个方法返回的是false
- # # django自动会吧request.user对象返回给模板中,不需要手动传递,只需要在模板中调用user即可
退出用户登陆
- 页面要显示退出按钮,
- 点击退出要调用退出函数,清除session,退出,跳转到登录页,
- 使用的也是使用的django的认证系统提供的logout,
- from django.contrib.auth import authenticate, login, logout
- 退出的时候返回登陆页面,还是使用了反向解析,
###########################################
上面就是一连串的操作,
- 1,登陆判断,这是使用的内置的认证系统,
- 2,欢迎信息,这是使用的内置的认证系统,
- 3,退出登陆,这是使用的内置的认证系统,
##################################################
用户中心-个人信息页面完善,
- 需要获取用户的个人信息,
- 展示默认的收获地址,
- 获取用户最近的浏览记录,
- 需求:
- 1,什么时候添加浏览记录?肯定是访问商品的详情页面的时候(在商品详情对应的视图中,),需要添加历史浏览记录,
- 2,什么时候获取浏览记录?访问用户个人中心的时候,获取历史浏览记录,
- 3,历史浏览记录存储在哪里?如果放在数据库,每次客户浏览都要操作数据库,数据库会压力很大,所以怎么存?我们就可以使用redis数据库,
- 4,怎么存储到redis中?存储历史浏览记录的格式是什么样子的?这个就要分析,redis中有五种数据类型,你存储就是这五种,
- 分析:
- 存储用户的历史浏览记录时是所有用户用一条保存,还是每一个用户的浏览记录使用一条数据保存,
- 如果所有用户用一条保存,可以使用hash,属性标记用户,user_用户id:商品ID,但是我们讲过hash的值只能是字符串,但是商品id可以有很多个,可以使用字符串,然后使用逗号隔开,又浏览商品了,还需要往字符串添加值,这就是使用hash,需要不停的操作字符串,
- 格式:history: user_用户id:‘1,2,3’
- 每一个用户的浏览记录使用一条数据保存,我们选择什么数据类型,
- 格式:history: user_用户id:[1,2,3],
- 我们可以把最新的插入到最左侧,所以浏览记录就是从左往右操作,所以无论加数据还是取数据,都比上一个好,
- 结论:对比之后,我们使用list才存储浏览记录,
- 整个设计思路,以及操作思路都非常的清晰,对我非常的有用,
- 我们进行图片的存储是使用fastDFS文件系统的,后面我就研究一下,
用户中心-订单信息页面完善,
- 订单信息
用户中心-地址信息页面完善
- 有了页面,页面有一个表单,post的时候可以提交新的地址信息,
- AddressView类,需要做两个事情,
- get的时候,获取收获地址,
- post的时候,接收表单信息,校验数据,保存到数据库,返回应答
- 模型管理类方法的封装:
- 根据条件查询一个默认收货地址,很多地方用到了,
- 是否可以封装一下,
- 这个封装的思想要好好理解一下,
- 整体的地址页面还没有开发完整,
- 地址列表的展示,
- 地址的删除,修改,等等,这些后续的再去做,现在不做,
######################################################################
系统中的图片存储
- 我们进行图片的存储是使用fastDFS文件系统的,后面我就研究一下,单独开一个博客
python和fastdfs的交互:
- 使用python往fastdfs上传文件,这是开发人员必须要掌握的,
- 需要安装一个包,pip install fdfs-py-master.zip
- 安装过程:https://www.cnblogs.com/wanghaiqi24/p/10035896.html,报错也按照这个里面的
- 重启pycharm,这一步一定要重启,
- 在外部访问图片:http://192.168.100.128:8888/group1/M00/00/00/wKhkgF3W1aqAY8vvAAV_23Ar72I886.png
- 能看到图片说明fastdfs和Nginx都是服务启动的,
项目中上传和使用图片的流程:
- 解决了文件的海量存储,存储空间的扩展方便,重复文件只存储一遍,
- 通过admin后台管理页面,上传图片,默认保存在django服务器
- 现在我们不保存在django中了,而是保存在fdfs文件存储服务器,
- 最终会返回一个文件的id,这个id要保存在对应的表中,
- 整个上传的流程就是这样的,
- 现在浏览器要请求页面了,访问页面,要把图片的地址进行一个替换,
- 所以图片地址前面需要写上Nginx的地址,渲染成这个内容,<img src='http://192.168.100.128:8888/文件id'>
- 然后浏览器识别到图片路径,会根据路径请求Nginx,然后Nginx在fastdfs中取出图片,返回给浏览器,就可以显示页面图片了,会发现这个过程是没有经过django的,这样就会快了,
- 整个流程关键是上传的点,我们需要修改django的上传行为,不让他上传到django服务器了,而且到fastdfs+Nginx,,,获取的流程只要配置fastdfs+Nginx好了就可以了,
自定义文件存储类:
- 修改django的上传行为,我们要对django进行二次开发,这个技能非常的关键,这说明对django的原理已经非常的了解了,
- django中有一个filesystemstorage类,是默认存储在media root中,但是我们不能改动django的源码,它有一个父类,我们只需要继承父类重写这个方法就可以了,就可以边界我们自定义的文件存储类了,
- from django.core.files.storage import Storage
- 配置文件fdfs-client:
- base_path=D:\AI\fdfs-client-log
- tracker_server=192.168.100.128:22122
- 定义自定义文件存储类,
使用admin页面测试文件存储类:
- http://127.0.0.1:8000/admin/login/,访问这个页面是需要做一些django的app模块里面做配置的,
- 具体的django的admin内容还需要继续学习,
- 需要创建一个admin用户,如何创建?
-
D:\AI\dailyfresh>python manage.py createsuperuser
Username: admin
Email address:
Password:
Password (again):
Superuser created successfully. - 登陆就成功了
- 增加一个商品分类的图片,点击保存,看看是否成功,
- [-] Error: 10060 connect to 192.168.100.128:22122. 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。.
- 换包的问题,我待会看看,借这个机会,我再次梳理一下,fastdfs+Nginx的安装配置过程,单独开一个博客
- 继续已经解决问题了,
- 已经可以成功保存数据了,
改进我们的自定义文件存储类:
- 把配置文件的加载地址不要写死,ip也不要写死,要动态的使用,
- 在init里面做,增加几个参数,
- client_conf,这是配置文件的加载地址,
- base_url,这是Nginx的地址,
- 并且把地址都写到settings里面去,这样代码都不需要动,你只需要改动配置文件,
- 这个文件的名字不是固定的,有意义就可以了,如果是django的配置文件就不能随便改动,一定要django的,
关于fastdfs的总结:
- 为什么要使用fastdfs,容量扩张问题,文件重复问题,获取图片效率问题,
- 上传和下载流程,
- 自定义存储类的编写,