Django项目之Web端电商网站的实战

发布时间:2019-05-23 21:02:31编辑:auto阅读(2494)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

    接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/88810060

    目录

    一丶模板文件继承

    二丶用户中心页面显示

    三丶登录验证以及登录后跳转的地址

    四丶封装login_required方法

    五丶登录后显示用户名以及退出登录

    六丶用户中心-地址

    七丶用户中心-信息

    八丶分布式文件系统FastDFS

    九丶Nginx配置FastDFS使用的安装和配置

    十丶Python与FastDFS进行交互


    一丶模板文件继承

    1.分析网页中共有的模块,定义父模板

    • step1 在templates目录下常见base.html文件,用于主页(index.html),登录页(login.html)以及注册页(register.html)模板的继承
    {# 首页 注册 登录 #}
    <!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>
    • step2 在templates目录下常见base_detail_list.html文件,这个模板文件继承需base.html,用于详情页(detail.html),列表页(list.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 %}
    • step3 在templates目录下常见base_no_cart.html文件,这个模板文件继承需base.html,用于购物车页(cart.html),提交订单页(place_order.html)模板的继承
    {# 购物车 提交订单 #}
    {% 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">|&nbsp;&nbsp;&nbsp;&nbsp;{% 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 %}
    • step4 在templates目录下常见base_user_center.html文件,这个模板文件继承需base_no_cart.html,用于用户中心三个页面(user_center_info.html)(user_center_order.html)(user_center_site.html)模板的继承
    {# 用户中心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.注册页登录页主页继承于父模板

    • step1 编写注册页面(register.html)继承于base.html

    • step2 编写登录页面(login.html)继承于base.html 

    •  step3 编写主页(index.html)继承于bases.html

    • step4 测试页面显示是否正确

    3.用户中心三个页面继承于父模板

    •  step1 编写(user_center_info.html)继承于base_user_center.html

    • step2  编写(user_center_order.html)继承于base_user_center.html

    • step3  编写(user_center_site.html)继承于base_user_center.html

    4.购物车页提交订单页继承于父模板

    • step1 编写购物车页(cart.html)继承于base_no_cart.html

    • step2 编写提交订单页(place_order.html) 继承于base_no_cart.html

    5.商品详情页商品列表页继承于父模板

    • step1  编写详情页(detail.html)继承于base_detail_list.html

    • step2  编写列表页(list.html)继承于base_detail_list.html

    二丶用户中心页面显示

    1.定义类视图

    • step1 定义UserInfoView类并定义get方法,用于显示用户信息页面
    # /user
    class UserInfoView(View):
        """用户中心-信息"""
        def get(self, request):
            """显示页面"""
            return render(request, "user_center_info.html")
    • step2 定义UserOrderView类并定义get方法,用于显示用户订单页面
    class UserOrderView(View):
        """用户中心-订单"""
        def get(self, request):
            """显示页面"""
            return render(request, "user_center_order.html")
    • step3 定义UserAddressView类并定义get方法,用于显示用户地址页面
    # /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.输入路由地址进行页面显示

    • step1 用户信息页面

    • step2 用户订单页面

    • step3 用户地址页面

    4.修改用户中心链接地址以及激活active选择器

    • step1 在用户中心页面点击个人信息,全部订单以及收货地址时,跳转到正确链接地址

     

    • step2 在base_user_center.html父模板中使用反向解析定义链接地址
    <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>
    •  step3 在用户中心三个类视图中在返回模板文件时,传递三个页面不同的参数,根据参数来判断active激活哪个页面
    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"})
    
    • step4 紧接着在base_user_center.html父模板对后端返回的数据进行判断处理
    <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>
    • step5 测试效果

    三丶登录验证以及登录后跳转的地址

    1.登录验证

    • step1 导入django模块中的login_required方法,验证用户是否是登录状态,也就是获取session的值,如果用户是登录状态,那么则可以访问需要登录成功后所访问的页面,如果用户未登录,直接访问需要登录后才能看到的页面,则login_required方法默认跳转到http://127.0.0.1:8000/accounts/login/?next=/user/页面
    from django.contrib.auth.decorators import login_required
    • step2 在df_user/urls中对用户中心信息页添加login_required登录验证方法
    url(r"^$", login_required(UserInfoView.as_view()), name="user"),  # 用户中心-信息

    说明:这里之所以换了个浏览器是因为之前的谷歌浏览器有登录成功保存的session,博主不想清除浏览缓存

    •  step4 在官网文档中调用login_required方法,设置验证不成功跳转的地址,则需要在项目settings配置文件中配置LOGIN_URL,设置为登录地址

    2.登录成功后跳转的地址

    • step1 根据login_required方法验证未登录状态跳转的登录地址http://127.0.0.1:8000/user/login?next=/user/,在LoginView类视图post方法中,获取请求地址next参数的值,如果当用户访问的是http://127.0.0.1:8000/user/login登录页面,则next请求地址参数中的next参数无法获取,所以设置默认值为反向解析主页地址
    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"), # 用户中心-地址

    四丶封装login_required方法

    1.定义工具类

    • step1 在项目目录下创建utils包,在utils包下创建mixin.py文件

    • step2 在mixin.py文件中创建LoginRequiredMixin类,封装login_required方法
    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方法

    • step1 继承LoginRequiredMixin类

    • step2 去掉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"),  # 用户中心-地址
    • step3 验证成功

    五丶登录后显示用户名以及退出登录

    1.登录后显示用户名不显示登录注册功能选项

    • step1 Django框架默认会给前端模板文件传递request.user对象,如果用户是登录状态访问页面会返回User类的对象user,如果未登录则返回AnonymousUser实力对象,当给前端模板文件返回的是user对象(已登录)则这个实力对象去调is_authenticated方法则会返回True,(未登录)AnonymousUser实力对象去调用is_authenticated方法则会返回False,在base.html模板文件中根据user对象进行判断,如果没有使用重复模板的继承复用,则需要在有class=‘header_con’模块的模板文件中一一进行判断,在此体现出重复内容模板继承的重要性
    {% 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 %}
    • step2 直接刷新已登录后的主页进行验证

    2.退出登录

    • step1 在base.html模板文件中添加退出按钮
    <div class="login_btn fl">
    	<span>|</span>
    	<a href="{% url 'user:logout' %}">退出</a>
    </div>
    •  step2 在views中定义Logout类视图完成退出功能
    # /user/logout
    class LogoutView(View):
        """退出"""
        def get(self, request):
            logout(request)
            # 退出后跳转到主页
            return redirect(reverse("goods:index"))
    
    • step3 在urls中定义退出路由
    url(r"^logout$", LogoutView.as_view(), name="logout"),  # 注销

    3.验证登录登出功能

    六丶用户中心-地址

     1.在UserAddressView类中定义post方法添加地址

    • step1 接收用户填写的数据
    receiver = request.POST.get("receiver")  # 收件人
    addr = request.POST.get("addr")  # 地址
    zip_code = request.POST.get("zip_code")  # 邮编
    phone = request.POST.get("phone")  # 手机号
    • step2  验证数据完整性,邮编可以不填
    if not all([receiver, addr, phone]):
        return render(request, "user_center_site.html", {"error_msg":"数据不完整"})
    • step3 验证手机号格式
    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": "手机号格式不正确"})
    • step4 加收货地址,当用户已存在默认收货地址,添加的地址不作为默认收货地址,否则作为默认收货地址, 因为此界面输入登录后的界面,所以django保存了user对象
    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
    • step5 保存收货地址,跳转到地址页
    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对象

    • step1 通过登录后的user对象在Address类中获取该用户的地址对象,根据该对象中的is_default字段,设置值为True(也就是该用户存在默认地址)进行数据库df_address表查询,如果出现异常表示该用户并没有收货地,则设置address对象为None,最后将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})
    • step2 在用户地址前端模板文件中进行判断,当后端返回的address对象不为空时则从该对象中获取用户填写的收件地址,收件人以及收件人电话,否则返回None
    <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.测试

    • step1 添加收货地址

    • step2 查看数据库

     4.定义地址模型类管理器

    • step1  在df_use模块models.py文件中创建AddressManager模型类,在类中定义一个方法用于操作模型类对应的数据表,将视图中的UserAddressView类里获取登录后用户的地址对象代码拷贝到此方法中,进行封装
    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
    • step2 在df_use模块models.py文件中地址类(Address)中创建AddressManager的实例对象objects
    objects = AddressManager()
    • step3 回到UserAddressView类视图中,注释掉try包含的代码,直接通过调用Address.objects.get_default_address方法来获取address对象
     address = Address.objects.get_default_address(user)
    • step4 测试添加地址

    说明:收货地址栏可以添加一个复选框,在这个复选框中显示出该用户所有的收货地址,当选择某一个收货地址时,则设置改收货地址的is_default值为1

     七丶用户中心-信息

    1.显示基本信息

    • step1 在UserInfoView类视图get方法中获取用户基本信息
    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})
    • step2 在模板文件user_center_info.html中获取后端返回的用户地址信息对象,根据该对象来对页面信息进行处理
    <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.获取用户历史浏览记录

    • step1 分析历史浏览记录存储设计
    1.什么时候添加历史浏览记录
      当用户点击进入某个商品详情页时,需要添加历史浏览记录
    2.什么时候获取历史浏览记录
      在用户信息页面显示
    3.历史浏览记录往哪里存储
      存储在内存级的redis数据库中提高读写效率
    4.以哪种数据格式进行存储
      以list数据格式进行存储
    • step2 通过django_redis包封装好的get_redis_connection方法获取redis中的StrictRedis类的实例对象 ,这个方法接收参数为default与settings配置文件中django缓存数据库设置名default一致
     conn = get_redis_connection("default")
    • step3 设置redis数据库的key
    history_key = "history_%d" % user.id
    • step4 获取用户最新浏览的5个商品的id
     sku_ids = conn.lrange(history_key, 0 ,4)
    • step5 遍历查询到的用户sku_ids,根据遍历出的的id查询出对应的商品信息,之所以定义一个空列表是为了让存入列表中的商品信息,是以先进后出的方式进行排列,因为浏览记录第一个即是用户最后一个浏览的商品详情
    goods_list = []
    for sku_id in sku_ids:
        goods = GoodsSKU.objects.get(id=sku_id)
        goods_list.append(goods)
    • step6 构造返回前端模板响应数据
    content = {"page":"user",
               "address":address,
               "goods_list":goods_list
               }
    
    return render(request, "user_center_info.html", content )
    • step7 在user_center_info模板文件中,获取后端返回的数据,并进行判断处理
    {% 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 %}
    • step8 直接刷新http://127.0.0.1:8000/user/用户中心信息页,因为商品详情还没有做,所以数据库中并没有存储历史浏览的商品信息,所以显示无历史浏览记录

    八丶分布式文件系统FastDFS

    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

    • step1 解压缩libfastcommon-master.zip包,进入到libfastcommon-master的目录中,执行 ./make.sh进行编译

    • step2 执行 sudo ./make.sh install进行安装

    • step3 解压缩fastdfs-master.zip,进入到 fastdfs-master目录中,执行 ./make.sh进行编译

    • step4 执行 sudo ./make.sh install进行安装

    8.配置跟踪服务器tracker

    •  step1 安装完fdfs后在fdfd目录下会产生一个fdfs的配置文件样例 tracker.conf.sample,将该配置文件拷贝并重命名到当前路径下名为tracker.conf
    sudo cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf

    • step2 在/home/taogang/目录中创建目录 fastdfs/tracker两个层级目录,记得修改(/home/用户名)

    • step3 编辑/etc/fdfs/tracker.conf配置文件,修改 base_path=/home/taogang/fastdfs/tracker
    sudo vim /etc/fdfs/tracker.conf

    9.配置存储服务器storage 

    • step1 将fdfs目录下的storage.conf.sample配置文件拷贝并重命名到当前路径下名为tracker.conf
    sudo cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf

    • step2 在/home/taogang/fastdfs/ 目录中创建目录 storage

    •  step3 编辑/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.测试是否安装成功

    • step1 将fdfs目录下的client.conf.sample配置文件拷贝并重命名到当前路径下名为client.conf
    sudo cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf 

    • step2 编辑/etc/fdfs/client.conf配置文件,修改如下配置
    sudo vim /etc/fdfs/client.conf
    base_path=/home/taogang/fastdfs/tracker
    tracker_server=你的ubuntu虚拟机的ip地址:22122

    • step3 上传文件测试,使用fdfs_upload_file /etc/fdfs/client.conf 要上传的文件 ,如果返回类似group1/M00/00/00/xxxxxxxxxxxxxxxxxxxx.sql(上传文件的后缀名)的文件id则说明文件上传成功

    九丶Nginx配置FastDFS使用的安装和配置

    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

    • step1 解压缩 nginx-1.8.1.tar.gz和fastdfs-nginx-module-master.zip这两个包,进入nginx-1.8.1目录中,执行sudo ./configure --prefix=/usr/local/nginx/ --add-module=(fastdfs-nginx-module-master)解压后的目录的绝对路径/src

    结果报错了,看提示是缺少PCRE库 

    • step2 安装pcre,依次执行下面三条命令
    sudo apt-get update
    sudo apt-get install libpcre3 libpcre3-dev
    sudo apt-get install openssl libssl-dev
    • step3 安装pcre成功后再次执行configure命令,生成Makefile成功

    • step4 编译

    • step5 安装 

    • step6 安装成功后测试nginx是否安装成功,执行./nginx -t ,结果报错了,根据报错提示,当前用户对该nginx文件下的文件没有读写操作,执行su root切换到root权限,再次执行提示成功

    • step7 拷贝fastdfs-nginx-module-master解压后的目录中src下的mod_fastdfs.conf 到 /etc/fdfs/mod_fastdfs.conf命名为mod_fastdfs.conf

    • step8 编辑/etc/fdfs/mod_fastdfs.conf配置文件,进行以下修改
    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

    •  step9 拷贝解压缩的fastdfs-master目录下conf目录中http.conf和mime.types配置文件到 /etc/fdfs目录下

    • step10 编辑/usr/local/nginx/conf/目录下的nginx.conf配置文件,进行如下编写
    sudo vim /usr/local/nginx/conf/nginx.conf

    • step11 开启nginx服务

    3.测试Nginx服务器配合FastDFS系统进行文件上传与获取

    • step1 开启fdfs服务,上传桌面上的goods_detail.jpg图片,返回文件id,这个id需记住,为了下一步的测试

    • step2 打开浏览器输入127.0.0.1:8888(nginx配置的端口)/(上传成功返回的文件id),成功显示出上传的图片

     十丶Python与FastDFS进行交互

    • step1 进入博主自己项目的虚拟环境(django_py2),使用pip安装fdfs_client-py包

    • step2 查看虚拟环境中是否存在fdfs_client-py模块

    • step3 上传测试(上传成功)

    • step5 归纳:python作为客户端与fdfs系统进行交互并上传文件成功,安装nginx服务器配合fdfs系统使用成功,最后通过访问配置nginx服务group[0-9]以及8888端口在浏览器中访问python客户端上产到fdfs系统上的文件,非常成功

关键字