8. 项目实战后台之商品信息管理

  • 本页面完成项目后台管理的商品信息模块操作

(1). 商品信息数据表:goods

  • 在数据库 shopdb 中创建goods表,若此表已存在请跳过

CREATE TABLE `goods` (                               
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,     
  `typeid` int(11) unsigned NOT NULL,                
  `goods` varchar(32) NOT NULL,                      
  `company` varchar(50) DEFAULT NULL,                
  `content` text,                                    
  `price` double(6,2) unsigned NOT NULL,             
  `picname` varchar(255) DEFAULT NULL,               
  `store` int(11) unsigned NOT NULL DEFAULT '0',     
  `num` int(11) unsigned NOT NULL DEFAULT '0',       
  `clicknum` int(11) unsigned NOT NULL DEFAULT '0',  
  `state` tinyint(1) unsigned NOT NULL DEFAULT '1',  
  `addtime` datetime DEFAULT NULL,                   
  PRIMARY KEY (`id`),                                
  KEY `typeid` (`typeid`)                            
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

(2). 定义模型Model类

  • 进入common应用目录中,编辑:myobject/common/models.py 模型文件,添加如下代码
from django.db import models

from datetime import datetime

#商品信息模型
class Goods(models.Model):
    typeid = models.IntegerField()
    goods = models.CharField(max_length=32)
    company = models.CharField(max_length=50)
    content = models.TextField()
    price = models.FloatField()
    picname = models.CharField(max_length=255)
    store = models.IntegerField(default=0)
    num = models.IntegerField(default=0)
    clicknum = models.IntegerField(default=0)
    state = models.IntegerField(default=1)
    addtime = models.DateTimeField(default=datetime.now)

    def toDict(self):
        return {'id':self.id,'typeid':self.typeid,'goods':self.goods,'company':self.company,'price':self.price,'picname':self.picname,'store':self.store,'num':self.num,'clicknum':self.clicknum,'state':self.state}

    class Meta:
        db_table = "goods"  # 更改表名

(3). 项目urls路由信息配置

  • 打开根路由文件:myobject/myadmin/urls.py路由文件,编辑路由配置信息

from django.conf.urls import url

from myadmin.views import index,users,type,goods

urlpatterns = [
    ...
    # 后台商品信息管理
    url(r'^goods$', goods.index, name="myadmin_goods_index"),
    url(r'^goods/add$', goods.add, name="myadmin_goods_add"),
    url(r'^goods/insert$', goods.insert, name="myadmin_goods_insert"),
    url(r'^goods/del/(?P<gid>[0-9]+)$', goods.delete, name="myadmin_goods_del"),
    url(r'^goods/edit/(?P<gid>[0-9]+)$', goods.edit, name="myadmin_goods_edit"),
    url(r'^goods/update/(?P<gid>[0-9]+)$', goods.update, name="myadmin_goods_update"),
]

 (4). 编辑视图文件

  • 新建视图文件:myobject/myadmin/views/goods.py 视图文件,并进行编辑
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect
from django.core.urlresolvers import reverse

from common.models import Types,Goods
from PIL import Image
from datetime import datetime
import time,json,os

# ==============后台商品信息管理======================
# 浏览商品信息
def index(request):
    # 执行数据查询,并放置到模板中
    list = Goods.objects.all()
    for ob in list:
        ty = Types.objects.get(id=ob.typeid)
        ob.typename = ty.name
    context = {"goodslist":list}
    return render(request,'myadmin/goods/index.html',context)

# 商品信息添加表单
def add(request):
    # 获取商品的类别信息
    list = Types.objects.extra(select = {'_has':'concat(path,id)'}).order_by('_has')
    context = {"typelist":list}
    return render(request,'myadmin/goods/add.html',context)

#执行商品类别信息添加 
def insert(request):
    try:
        # 判断并执行图片上传,缩放等处理
        myfile = request.FILES.get("pic", None)
        if not myfile:
            return HttpResponse("没有上传文件信息!")
        # 以时间戳命名一个新图片名称
        filename= str(time.time())+"."+myfile.name.split('.').pop()
        destination = open(os.path.join("./static/goods/",filename),'wb+')
        for chunk in myfile.chunks():      # 分块写入文件  
            destination.write(chunk)  
        destination.close()

        # 执行图片缩放
        im = Image.open("./static/goods/"+filename)
        # 缩放到375*375:
        im.thumbnail((375, 375))
        # 把缩放后的图像用jpeg格式保存:
        im.save("./static/goods/"+filename, 'jpeg')
        # 缩放到220*220:
        im.thumbnail((220, 220))
        # 把缩放后的图像用jpeg格式保存:
        im.save("./static/goods/m_"+filename, 'jpeg')
        # 缩放到75*75:
        im.thumbnail((75, 75))
        # 把缩放后的图像用jpeg格式保存:
        im.save("./static/goods/s_"+filename, 'jpeg')

        # 获取商品信息并执行添加
        ob = Goods()
        ob.goods = request.POST['goods']
        ob.typeid = request.POST['typeid']
        ob.company = request.POST['company']
        ob.price = request.POST['price']
        ob.store = request.POST['store']
        ob.content = request.POST['content']
        ob.picname = filename
        ob.state = 1
        ob.addtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        ob.save()
        context = {'info':'添加成功!'}
    except Exception as err:
        print(err)
        context = {'info':'添加失败!'}

    return render(request,"myadmin/info.html",context)

# 执行商品信息删除
def delete(request,gid):
    try:
        # 获取被删除商品信的息量,先删除对应的图片
        ob = Goods.objects.get(id=gid)
        #执行图片删除
        os.remove("./static/goods/"+ob.picname)   
        os.remove("./static/goods/m_"+ob.picname)   
        os.remove("./static/goods/s_"+ob.picname)
        #执行商品信息的删除 
        ob.delete()
        context = {'info':'删除成功!'}
    except Exception as err:
        print(err)
        context = {'info':'删除失败!'}
    return render(request,"myadmin/info.html",context)

# 打开商品类别信息编辑表单
def edit(request,gid):
    try:
        # 获取要编辑的信息
        ob = Goods.objects.get(id=gid)
        # 获取商品的类别信息
        list = Types.objects.extra(select = {'_has':'concat(path,id)'}).order_by('_has')
        # 放置信息加载模板
        context = {"typelist":list,'goods':ob}
        return render(request,"myadmin/goods/edit.html",context)
    except Exception as err:
        print(err)
        context = {'info':'没有找到要修改的信息!'}
    return render(request,"myadmin/info.html",context)

# 执行商品类别信息编辑
def update(request,gid):
    try:
        b = False
        oldpicname = request.POST['oldpicname']
        if None != request.FILES.get("pic"):
            myfile = request.FILES.get("pic", None)
            if not myfile:
                return HttpResponse("没有上传文件信息!")
            # 以时间戳命名一个新图片名称
            filename = str(time.time())+"."+myfile.name.split('.').pop()
            destination = open(os.path.join("./static/goods/",filename),'wb+')
            for chunk in myfile.chunks():      # 分块写入文件  
                destination.write(chunk)  
            destination.close()
            # 执行图片缩放
            im = Image.open("./static/goods/"+filename)
            # 缩放到375*375:
            im.thumbnail((375, 375))
            # 把缩放后的图像用jpeg格式保存:
            im.save("./static/goods/"+filename, 'jpeg')
            # 缩放到220*220:
            im.thumbnail((220, 220))
            # 把缩放后的图像用jpeg格式保存:
            im.save("./static/goods/m_"+filename, 'jpeg')
            # 缩放到75*75:
            im.thumbnail((75, 75))
            # 把缩放后的图像用jpeg格式保存:
            im.save("./static/goods/s_"+filename, 'jpeg')
            b = True
            picname = filename
        else:
            picname = oldpicname
        ob = Goods.objects.get(id=gid)
        ob.goods = request.POST['goods']
        ob.typeid = request.POST['typeid']
        ob.company = request.POST['company']
        ob.price = request.POST['price']
        ob.store = request.POST['store']
        ob.content = request.POST['content']
        ob.picname = picname
        ob.state = request.POST['state']
        ob.save()
        context = {'info':'修改成功!'}
        if b:
            os.remove("./static/goods/m_"+oldpicname) #执行老图片删除  
            os.remove("./static/goods/s_"+oldpicname) #执行老图片删除  
            os.remove("./static/goods/"+oldpicname) #执行老图片删除  
    except Exception as err:
        print(err)
        context = {'info':'修改失败!'}
        if b:
            os.remove("./static/goods/m_"+picname) #执行新图片删除  
            os.remove("./static/goods/s_"+picname) #执行新图片删除  
            os.remove("./static/goods/"+picname) #执行新图片删除  
    return render(request,"myadmin/info.html",context)

(5). 编写模板文件

  • 5.1. 打开父类模板:/templates/myadmin/base.html ,编辑导航栏代码
    ...
    <li class="nav-header">
        商品信息管理
    </li>
    <li>
        <a href="{% url 'myadmin_goods_index' %}"><i class="icon-list-alt"></i> 浏览商品信息</a>
    </li>
    <li>
        <a href="{% url 'myadmin_goods_add' %}"><i class="icon-list-alt"></i> 添加商品信息</a>
    </li>
    ...
  • 5.2. 后台商品信息浏览页模板:/templates/myadmin/goods/index.html

{% extends "myadmin/base.html" %}

{% block mainbody %}                
    <h4>
        商品信息管理
    </h4>
    <table class="table table-bordered table-striped">
        <thead>
            <tr>
                <th>id号</th>
                <th>商品名称</th>
                <th>商品类别</th>
                <th>图片</th>
                <th>单价</th>
                <th>点击量</th>
                <th>状态</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for vo in goodslist %}
            <tr>
                <td>{{ vo.id }}</td>
                <td>{{ vo.goods }}</td>
                <td>{{ vo.typename }}</td>
                <td><img src="/static/goods/s_{{ vo.picname }}" width="60"/></td>
                <td>{{ vo.price }}</td>
                <td>{{ vo.clicknum }}</td>
                <td>
                    {% if vo.state == 1 %}
                        新添加
                    {% elif vo.state == 2 %}
                        在售
                    {% else %}
                        下架
                    {% endif %}
                </td>
                <td>
                    <a href="{% url 'myadmin_goods_del' vo.id %}" class="view-link">删除</a>
                    <a href="{% url 'myadmin_goods_edit' vo.id %}" class="view-link">编辑</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>                
    <div class="pagination">
        <ul>
            <li class="disabled">
                <a href="#">&laquo;</a>
            </li>
            <li class="active">
                <a href="#">1</a>
            </li>
            <li>
                <a href="#">2</a>
            </li>
            <li>
                <a href="#">3</a>
            </li>
            <li>
                <a href="#">4</a>
            </li>
            <li>
                <a href="#">&raquo;</a>
            </li>
        </ul>
    </div>
{% endblock %}
  • 5.3. 后台商品信息添加表单页模板:/templates/myadmin/goods/add.html

{% extends "myadmin/base.html" %}

{% block mainbody %}                
    <h3>
        商品信息管理
    </h3>
    <form id="edit-profile" action="{% url 'myadmin_goods_insert' %}" class="form-horizontal" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <fieldset>
            <legend>添加商品信息</legend>
            <div class="control-group">
                <label class="control-label" for="input01">商品类别:</label>
                <div class="controls">
                    <select name="typeid">
                        {% for vo in typelist %}
                            <option 
                                {% if vo.pid == 0 %}
                                    disabled
                                {% endif %} 
                                 value="{{ vo.id }}">{{ vo.name }}</option>
                        {% endfor %}
                    </select>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">商品名称:</label>
                <div class="controls">
                    <input type="text" name="goods" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">生产厂家:</label>
                <div class="controls">
                    <input type="text" name="company" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">单价:</label>
                <div class="controls">
                    <input type="text" name="price" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">库存量:</label>
                <div class="controls">
                    <input type="text" name="store" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">商品图片:</label>
                <div class="controls">
                    <input type="file" name="pic" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">商品简介:</label>
                <div class="controls">
                    <textarea cols="40" style="width:450px" rows="10" name="content"></textarea>
                </div>
            </div>                        
            <div class="form-actions">
                <button type="submit" class="btn btn-primary">添加</button> <button type="reset" class="btn">重置</button>
            </div>
        </fieldset>
    </form>
{% endblock %}
  • 5.4. 后台商品信息编辑模板:/templates/myadmin/goods/edit.html

{% extends "myadmin/base.html" %}

{% block mainbody %}                
    <h3>
        商品信息管理
    </h3>
    <form id="edit-profile" action="{% url 'myadmin_goods_update' goods.id %}" class="form-horizontal" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="hidden" name="oldpicname" value="{{ goods.picname }}"/>
        <fieldset>
            <legend>编辑商品信息</legend>
            <div class="control-group">
                <label class="control-label" for="input01">商品类别:</label>
                <div class="controls">
                    <select name="typeid">
                        {% for vo in typelist %}
                            <option 
                                {% if vo.pid == 0 %}
                                    disabled
                                {% endif %}

                                {% if vo.id == goods.typeid %}
                                    selected 
                                {% endif %}
                                 value="{{ vo.id }}">{{ vo.name }}</option>
                        {% endfor %}
                    </select>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">商品名称:</label>
                <div class="controls">
                    <input type="text" name="goods" value="{{ goods.goods }}" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">生产厂家:</label>
                <div class="controls">
                    <input type="text" name="company" value="{{ goods.company }}" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">单价:</label>
                <div class="controls">
                    <input type="text" name="price" value="{{ goods.price }}" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">库存量:</label>
                <div class="controls">
                    <input type="text" name="store" value="{{ goods.store }}" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">商品图片:</label>
                <div class="controls">
                    <input type="file" name="pic" class="input-xlarge" id="input01"/>
                </div>
            </div>
            <div class="control-group">
                <label class="control-label" for="input01">状态:</label>
                <div class="controls">
                    <input type="radio" name="state" class="input-xlarge" id="input01" 
                    {% if goods.state == 1 %}
                        checked  
                    {% endif %}
                    value="1" /> 新商品 
                    <input type="radio" name="state" class="input-xlarge" id="input01" 
                    {% if goods.state == 2 %}
                        checked  
                    {% endif %}
                    value="2" /> 在售
                    <input type="radio" name="state" class="input-xlarge" id="input01" 
                    {% if goods.state == 3 %}
                        checked  
                    {% endif %}
                    value="3" /> 已下架
                </div>
            </div>    
            <div class="control-group">
                <label class="control-label" for="input01">商品简介:</label>
                <div class="controls">
                    <textarea cols="40" style="width:450px" rows="10" name="content">{{ goods.content }}</textarea>
                </div>
            </div>                        
            <div class="form-actions">
                <button type="submit" class="btn btn-primary">保存</button> <button type="reset" class="btn">重置</button>
            </div>
        </fieldset>
    </form>
    <br/>
    <img src="/static/goods/m_{{ goods.picname }}"/>
{% endblock %}

(6). 运行测试

[root@localhost myobject]# pwd
/python/myobject
[root@localhost myobject]# ls
manage.py  myadmin  myobject  myweb  static  templates
[root@localhost myobject]# python3 manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

April 08, 2018 - 12:20:30
Django version 1.11, using settings 'myobject.settings'
Starting development server at http://0:8000/
Quit the server with CONTROL-C.
^C[root@localhost myobject]#