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)
im.thumbnail((375, 375))
im.save("./static/goods/"+filename, 'jpeg')
im.thumbnail((220, 220))
im.save("./static/goods/m_"+filename, 'jpeg')
im.thumbnail((75, 75))
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)
im.thumbnail((375, 375))
im.save("./static/goods/"+filename, 'jpeg')
im.thumbnail((220, 220))
im.save("./static/goods/m_"+filename, 'jpeg')
im.thumbnail((75, 75))
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="#">«</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="#">»</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]#