发布于2019-08-08 15:38 阅读(527) 评论(0) 点赞(0) 收藏(1)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/88810060
目录
1.分析网页中共有的模块,定义父模板
{# 首页 注册 登录 #}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
{% load staticfiles %}
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
{# 网页标题内容块 #}
<title>{% block title %}{% endblock title %}</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
{# 网页顶部引入文件块 #}
{% block topfiles %}{% endblock topfiles %}
</head>
<body>
{# 网页顶部欢迎信息块 #}
{% block header_con %}
<div class="header_con">
<div class="header">
<div class="welcome fl">欢迎来到天天生鲜!</div>
<div class="fr">
<div class="login_info fl">
欢迎您:<em>张 山</em>
</div>
<div class="login_btn fl">
<a href="login.html">登录</a>
<span>|</span>
<a href="register.html">注册</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="../static/user_center_info.html">用户中心</a>
<span>|</span>
<a href="../static/cart.html">我的购物车</a>
<span>|</span>
<a href="../static/user_center_order.html">我的订单</a>
</div>
</div>
</div>
</div>
{% endblock header_con %}
{# 网页顶部搜索框块 #}
{% block search_bar %}
<div class="search_bar clearfix">
<a href="index.html" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
<div class="search_con fl">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
<div class="guest_cart fr">
<a href="#" class="cart_name fl">我的购物车</a>
<div class="goods_count fl" id="show_count">1</div>
</div>
</div>
{% endblock search_bar %}
{# 网站主体内容块 #}
{% block body %}{% endblock body %}
<div class="footer">
<div class="foot_link">
<a href="#">关于我们</a>
<span>|</span>
<a href="#">联系我们</a>
<span>|</span>
<a href="#">招聘人才</a>
<span>|</span>
<a href="#">友情链接</a>
</div>
<p>CopyRight © 2016 北京天天生鲜信息技术有限公司 All Rights Reserved</p>
<p>电话:010-****888 京ICP备*******8号</p>
</div>
{# 网页底部html元素块 #}
{% block bottom %}{% endblock bottom %}
{# 网页底部引入文件块 #}
{% block bottomfiles %}{% endblock bottomfiles %}
</body>
</html>
{# 详情页 列表页 #}
{% extends 'base.html' %}
{# 网站主体内容块 #}
{% block body %}
<div class="navbar_con">
<div class="navbar clearfix">
<div class="subnav_con fl">
<h1>全部商品分类</h1>
<span></span>
<ul class="subnav">
<li><a href="#" class="fruit">新鲜水果</a></li>
<li><a href="#" class="seafood">海鲜水产</a></li>
<li><a href="#" class="meet">猪牛羊肉</a></li>
<li><a href="#" class="egg">禽类蛋品</a></li>
<li><a href="#" class="vegetables">新鲜蔬菜</a></li>
<li><a href="#" class="ice">速冻食品</a></li>
</ul>
</div>
<ul class="navlist fl">
<li><a href="">首页</a></li>
<li class="interval">|</li>
<li><a href="">手机生鲜</a></li>
<li class="interval">|</li>
<li><a href="">抽奖</a></li>
</ul>
</div>
</div>
{# 详情页,列表页主体内容块 #}
{% block main_content %}{% endblock main_content %}
{% endblock body %}
{# 购物车 提交订单 #}
{% extends 'base.html' %}
{% load staticfiles %}
{# 网页顶部搜索框块 #}
{% block search_bar %}
<div class="search_bar clearfix">
<a href="index.html" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
<div class="sub_page_name fl">| {% block page_title %}{% endblock page_title %}</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
{% endblock search_bar %}
{# 用户中心3页面 #}
{% extends 'base_no_cart.html' %}
{% block title %}天天生鲜-用户中心{% endblock title %}
{% block page_title %}用户中心{% endblock page_title %}
{% block body %}
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="user_center_info.html" class="active">· 个人信息</a></li>
<li><a href="user_center_order.html">· 全部订单</a></li>
<li><a href="user_center_site.html">· 收货地址</a></li>
</ul>
</div>
{# 用户中心右侧内容块 #}
{% block right_content %}{% endblock right_content %}
</div>
{% endblock body %}
2.注册页登录页主页继承于父模板
3.用户中心三个页面继承于父模板
4.购物车页提交订单页继承于父模板
5.商品详情页商品列表页继承于父模板
1.定义类视图
# /user
class UserInfoView(View):
"""用户中心-信息"""
def get(self, request):
"""显示页面"""
return render(request, "user_center_info.html")
class UserOrderView(View):
"""用户中心-订单"""
def get(self, request):
"""显示页面"""
return render(request, "user_center_order.html")
# /user/address
class UserAddressView(View):
"""用户中心-地址"""
def get(self, request):
"""显示页面"""
return render(request, "user_center_site.html")
2.在df_user/urls中配置路由
url(r"^$", UserInfoView.as_view(), name="user"), # 用户中心-信息
url(r"^order$", UserOrderView.as_view(), name="order"), # 用户中心-订单
url(r"^address$", UserAddressView.as_view(), name="address"), # 用户中心-地址
3.输入路由地址进行页面显示
4.修改用户中心链接地址以及激活active选择器
<li><a href="{% url 'user:user' %}" class="active">· 个人信息</a></li>
<li><a href="{% url 'user:order' %}">· 全部订单</a></li>
<li><a href="{% url 'user:address' %}">· 收货地址</a></li>
return render(request, "user_center_info.html", {"page":"user"})
return render(request, "user_center_info.html", {"page":"order"})
return render(request, "user_center_info.html", {"page":"address"})
<ul>
<li><a href="{% url 'user:user' %}" {% if page == 'user' %}class="active"{% endif %}>· 个人信息</a></li>
<li><a href="{% url 'user:order' %}"{% if page == 'order' %}class="active"{% endif %}>· 全部订单</a></li>
<li><a href="{% url 'user:address' %}"{% if page == 'address' %}class="active"{% endif %}>· 收货地址</a></li>
</ul>
1.登录验证
from django.contrib.auth.decorators import login_required
url(r"^$", login_required(UserInfoView.as_view()), name="user"), # 用户中心-信息
说明:这里之所以换了个浏览器是因为之前的谷歌浏览器有登录成功保存的session,博主不想清除浏览缓存
2.登录成功后跳转的地址
next_url = request.GET.get("next", reverse("goods:index"))
response = redirect(next_url)
url(r"^order$", login_required(UserOrderView.as_view()), name="order"), # 用户中心-订单
url(r"^address$", login_required(UserAddressView.as_view()), name="address"), # 用户中心-地址
1.定义工具类
from django.contrib.auth.decorators import login_required # 验证是否登录
class LoginRequiredMixin(object):
@classmethod
def as_view(cls, **initkwargs):
view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
return login_required(view)
2.在用户中心类视图中继承LoginRequiredMixin类并在urls中去掉login_required方法
url(r"^$", UserInfoView.as_view(), name="user"), # 用户中心-信息
url(r"^order$", UserOrderView.as_view(), name="order"), # 用户中心-订单
url(r"^address$", UserAddressView.as_view(), name="address"), # 用户中心-地址
1.登录后显示用户名不显示登录注册功能选项
{% if user.is_authenticated %}
<div class="login_btn fl">
欢迎您:<em style="color: #f89752">{{ user.username }}</em>
</div>
{% else %}
<div class="login_btn fl">
<a href="/user/login">登录</a>
<span>|</span>
<a href="/user/register">注册</a>
</div>
{% endif %}
2.退出登录
<div class="login_btn fl">
<span>|</span>
<a href="{% url 'user:logout' %}">退出</a>
</div>
# /user/logout
class LogoutView(View):
"""退出"""
def get(self, request):
logout(request)
# 退出后跳转到主页
return redirect(reverse("goods:index"))
url(r"^logout$", LogoutView.as_view(), name="logout"), # 注销
3.验证登录登出功能
1.在UserAddressView类中定义post方法添加地址
receiver = request.POST.get("receiver") # 收件人
addr = request.POST.get("addr") # 地址
zip_code = request.POST.get("zip_code") # 邮编
phone = request.POST.get("phone") # 手机号
if not all([receiver, addr, phone]):
return render(request, "user_center_site.html", {"error_msg":"数据不完整"})
if not re.match(r'^1[3|4|5|7|8|9][0-9]{9}$', phone):
return render(request, "user_center_site.html", {"error_msg": "手机号格式不正确"})
user = request.user
try:
address = Address.objects.get(user=user, is_default=True)
except Address.DoesNotExist:
# 出现异常表示该用户还没有设置默认地址
address = None
if address:
is_default = False
else:
is_default = True
Address.objects.create(user=user, receiver=receiver, addr=addr, zip_code=zip_code, phone=phone, is_default=is_default)
return redirect(reverse("user:address"))
2.在UserAddressView类get方法中获取地址类Address对象
def get(self, request):
"""显示页面"""
# 获取用户的的收货地址
user = request.user
try:
address = Address.objects.get(user=user, is_default=True)
except Address.DoesNotExist:
# 出现异常表示该用户还没有设置默认地址
address = None
return render(request, "user_center_site.html", {"page":"address","address":address})
<div class="site_con">
<dl>
<dt>当前地址:</dt>
{% if address %}
<dd>{{ address.addr }} ({{ address.receiver }} 收) {{ address.phone }}</dd>
{% else %}
<dd style="color: red">无默认地址</dd>
{% endif %}
</dl>
</div>
3.测试
4.定义地址模型类管理器
class AddressManager(models.Manager):
"""地址模型类管理器"""
# 用于操作模型类对应的数据表
def get_default_address(self, user):
try:
address = self.get(user=user, is_default=True)
except self.model.DoesNotExist:
# 出现异常表示该用户还没有设置默认地址
address = None
return address
objects = AddressManager()
address = Address.objects.get_default_address(user)
说明:收货地址栏可以添加一个复选框,在这个复选框中显示出该用户所有的收货地址,当选择某一个收货地址时,则设置改收货地址的is_default值为1
1.显示基本信息
def get(self, request):
"""显示页面"""
# 获取用户地址信息
user = request.user
address = Address.objects.get_default_address(user)
return render(request, "user_center_info.html", {"page":"user", "address":address})
<ul class="user_info_list">
<li><span>用户名:</span>{{ user.username }}</li>
{% if address %}
<li><span>联系方式:</span>{{ address.phone }}</li>
<li><span>联系地址:</span>{{ address.addr }}</li>
{% else %}
<li><span>联系方式:</span>无</li>
<li><span>联系地址:</span>无</li>
{% endif %}
</ul>
2.获取用户历史浏览记录
1.什么时候添加历史浏览记录
当用户点击进入某个商品详情页时,需要添加历史浏览记录
2.什么时候获取历史浏览记录
在用户信息页面显示
3.历史浏览记录往哪里存储
存储在内存级的redis数据库中提高读写效率
4.以哪种数据格式进行存储
以list数据格式进行存储
conn = get_redis_connection("default")
history_key = "history_%d" % user.id
sku_ids = conn.lrange(history_key, 0 ,4)
goods_list = []
for sku_id in sku_ids:
goods = GoodsSKU.objects.get(id=sku_id)
goods_list.append(goods)
content = {"page":"user",
"address":address,
"goods_list":goods_list
}
return render(request, "user_center_info.html", content )
{% for goods in goods_list %}
<li>
<a href="detail.html"><img src="{{ goods.image.url }}"></a>
<h4><a href="detail.html">{{ goods.name }}</a></h4>
<div class="operate">
<span class="prize">¥{{ goods.price }}</span>
<span class="unit">{{ goods.price }}/{{ goods.unite }}</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
{% empty %}
无历史浏览记录
{% endfor %}
1.FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题
2.该项目之所以使用FastDFS进行图片存储,而不使用django管理员网页进行上传,是因为使用FastDFS对海量存储以及存储扩容方便,同时也解决了同文件重复的问题
3.FastDFS架构图
服务端两个角色:
Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集 Storage 集群的状态。
Storage:实际保存文件 Storage 分为多个组,每个组之间保存的文件是不同的。每 个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有 主从的概念。
4.文件上传流程
说明:客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文 件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名
组名:文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回, 需要客户端自行保存。
虚拟磁盘路径:storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了 store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。
数据两级目录:storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据 文件。
文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储 服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息
5.文件下载流程
6.开发环境搭建简易FastDFS架构
7.FastDFS安装
说明:FastDFS需要在Linux系统进行安装,网上查了资料并没有推出可以在Windows环境下安装的FastDFS版本,安装FastDFS之前需安装fastdfs依赖包libfastcommon-master.zip
8.配置跟踪服务器tracker
sudo cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
sudo vim /etc/fdfs/tracker.conf
9.配置存储服务器storage
sudo cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
sudo vim /etc/fdfs/storage.conf
base_path=/home/taogang/fastdfs/storage
store_path0=/home/taogang/fastdfs/storage
tracker_server=你的ubuntu虚拟机的ip地址:22122
10.启动tracker 和 storage
sudo service fdfs_trackerd start
sudo service fdfs_storaged start
11.测试是否安装成功
sudo cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
sudo vim /etc/fdfs/client.conf
base_path=/home/taogang/fastdfs/tracker
tracker_server=你的ubuntu虚拟机的ip地址:22122
1.说明:使用FastDFS分布式系统架构在用户量比较大的时候,用户对内容的获取效率是非常低的,为了提高效率需要借助Nginx服务器来配置FastDFS进行使用,Nginx服务器在处理静态文件的效率是很高的,因为Nginx服务器内核是epoll,上传资源使用fdfs系统,获取资源则借助nginx服务器来获取;需安装nginx-1.8.1.tar.gz和fastdfs-nginx-module-master.zip这两个包,fastdfs-nginx-module-master.zip这个包的作用就是让nginx服务器和fdfs系统进行关联配置的作用
2.安装nginx和fastdfs-nginx-module
结果报错了,看提示是缺少PCRE库
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install openssl libssl-dev
sudo vim /etc/fdfs/mod_fastdfs.conf
connect_timeout=10 # 连接fdfs超时时间
tracker_server=自己ubuntu虚拟机的ip地址:22122
url_have_group_name=true # 访问fdfs时带不带组的信息(group1)
store_path0=/home/python/fastdfs/storage
sudo vim /usr/local/nginx/conf/nginx.conf
3.测试Nginx服务器配合FastDFS系统进行文件上传与获取
作者:可以给我吃一口吗
链接:https://www.pythonheidong.com/blog/article/14998/beb0e0d48324b55c2952/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!