github地址:https://github.com/AboutTigerShark/dailyfresh
1.首先我们要创建一个虚拟环境并指定python版本,这里不说明虚拟环境怎么安装配置.
输入mkvirtualenv --python=/home/idot/py3/bin/python3.4.exe py3django创建虚拟环境
2.输入workon py3django进入虚拟环境,在这个虚拟环境中安装需要的依赖包
pip install django==1.8.2(我使用的django版本)
pip insatll PyMySQL (python连接mysql需要的模块,值得注意的是原本的mysql-python不支持py3.x所以用PyMySQL,但是在dailyfresh目录下的__init__.py文件中需要添加如下代码
import pymysql
pymysql.install_as_MySQLdb()
)
3.cd到一个存放源码的目录下,在此目录下创建django项目
输入django-admin startproject dailyfresh,dailyfresh是项目名
4.至此项目创建完成,这个项目总共有4个模块对应4个app,分别是用户管理模块user_manage,商品管理模块goods_manage,购物车管理模块cart_manage,订单管理模块order_manage
在项目的根目录下创建名为templates的文件夹用于存放静态网页文件,下面是静态网页文件的github地址
https://github.com/AboutTigerShark/dailyfresh_static_file
1.用户模块主要实现登录注册以及用户地址用户订单等,首先在创建完项目的路径下创建app,并在在setting.py中安装app(这里一次性把所有模块列出来是为了方便,实际我在做的时候是一个模块一个模块完成的)
创建app命令如下
python manage.py startapp user_manage
python manage.py startapp goods_manage
python manage.py startapp cart_manage
python manage.py startapp order_manage
setting.py
1.1 app的安装
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user_manage', # 用户管理模块
'goods_manage', # 商品管理模块
'cart_manage', # 购物车管理模块
'order_manage', # 订单管理模块
'tinymce', # 富文本编辑器
)
1.2 templates的路径设置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 网页等静态文件存放路径
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
1.3 mysql配置
需要在mysql中先建好数据库(create database dailyfresh charset=utf8;)再进行setting中的配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'USER': 'root', # 用户名
'PASSWORD': 'root', # 密码
'HOST': 'localhost', # IP地址,这里是本机用localhost
'PORT': '3306', # 默认端口3306
'NAME': 'dailyfresh', # 数据库名,需要事先创建好
}
}
1.4 其他静态文件(如图片)的存放以及文件上传的路径配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
MEDIA_ROOT = os.path.join(BASE_DIR, 'static')
# 部署后的文件上传目录
# MEDIA_ROOT = '/var/www/dailyfresh/static'
2.user_manage模型类的创建和迁移
models.py
from django.db import models
class UserInfo(models.Model):
uname = models.CharField(max_length=20) # 用户名
upwd = models.CharField(max_length=40) # 密码
uemail = models.CharField(max_length=30) # 邮箱
ureceive = models.CharField(max_length=20, default='') # 快递接收者
uadress = models.CharField(max_length=120, default='') # 送货地址
uzipcode = models.CharField(max_length=6, default='') # 邮编
uphonenumber = models.CharField(max_length=11, default='') # 电话号码
模型类创建好后需要迁移,迁移所需的命令如下(项目根目录下)
python manage.py makemigrations
python manage.py migrate
注意如果之前没有在setting中安装应用名,将无法迁移,迁移完成后可以去mysql中查看一下表是否新建成功
4.user_manage的视图
view.py
#coding = utf-8
from django.core.paginator import Paginator
from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from hashlib import sha1
from goods_manage.models import GoodsInfo
from order_manage.models import OrderInfo, OrderDetailInfo
from user_manage import login_decorator
from user_manage.models import UserInfo
# 判断用户名是否存在
def uname_exits(request):
uname = request.GET.get('uname')
count = UserInfo.objects.filter(uname=uname).count()
return JsonResponse({'count': count})
def register(request):
return render(request, 'user_manage/register.html')
# 注册表单的处理
def register_handle(request):
post = request.POST
uname = post['user_name']
upwd = post['pwd']
upwd2 = post['cpwd']
uemail = post['email']
if upwd2 != upwd:
return redirect('/user/register/')
sha = sha1()
sha.update(upwd.encode('utf8'))
upwd3 = sha.hexdigest()
userinfo = UserInfo()
userinfo.uname = uname
userinfo.upwd = upwd3
userinfo.uemail = uemail
userinfo.save()
return redirect('/user/login/')
def login(request):
uname = request.COOKIES.get('uname', '') # 从cookie中取用户名,取不到置为空
context = {'title': '登录', 'error_name': 0, 'error_pwd': 0, 'uname': uname}
return render(request, 'user_manage/login.html', context)
# 登录表单的处理
def login_handle(request):
post = request.POST
uname = post['username']
upwd = post['pwd']
remember_name = post.get('remmamber_name', 0)
user = UserInfo.objects.filter(uname=uname)
if(len(user) == 1):
sha = sha1()
sha.update(upwd.encode('utf8'))
if(sha.hexdigest() == user[0].upwd):
url = request.COOKIES.get('url', '/goods/index/') # 登录成功跳转到先前的url
red = HttpResponseRedirect(url) # HttpResponseRedirect继承于HttpResponse.
if(remember_name != 0):
red.set_cookie('uname', uname)
else:
red.set_cookie('uname', uname, max_age=-1)
request.session['user_id'] = user[0].id
request.session['user_name'] = uname
return red
else:
context = {'title': '登录', 'error_name': 0, 'error_pwd': 1, 'uname': uname, 'upwd': upwd}
return render(request, 'user_manage/login.html', context)
else:
context = {'title': '登录', 'error_name': 1, 'error_pwd': 0, 'uname': uname, 'upwd': upwd}
return render(request, 'user_manage/login.html', context)
# 退出登录状态时清空session
def logout(request):
request.session.flush()
return redirect('/goods/index/')
# 用户信息的显示
@login_decorator.login
def info(request):
goods_ids = request.COOKIES.get('goods_id', '')
goods_ids1 = goods_ids.split(',')
goods_list = []
for goods_id in goods_ids1:
try: # 这里加个异常判断不然goods_id为空的话就会抛异常,空字符串不能转为int
goods_list.append(GoodsInfo.objects.get(id=int(goods_id)))
except ValueError:
pass
uname = request.session.get('user_name', 'zhangsan')
uemail = UserInfo.objects.get(pk=request.session['user_id']).uemail
context = {'uname': uname, 'uemail': uemail, 'page_name': 1, 'goods_list': goods_list}
return render(request, 'user_manage/user_center_info.html', context)
# 用户地址的存储
@login_decorator.login
def site(request):
user = UserInfo.objects.filter(pk=request.session['user_id'])[0] # 返回的是一个queryset集合,集合没有save()方法,取第一个元素即可.
if request.method == 'POST': # 区分超链接和POST请求,如果是超链接请求,不执行if块
post = request.POST
user.ureceive = post.get('receiver')
user.uadress = post.get('address')
user.uzipcode = post.get('zipcode')
user.uphonenumber = post.get('phonenumber')
user.save()
context = {'title': '用户中心', 'user': user, 'page_name': 1}
return render(request, 'user_manage/user_center_site.html', context)
# 用户订单的显示,按是否支付和时间排序
@login_decorator.login
def user_center_order(request, pageindex):
uid = request.session.get('user_id')
orderinfos = OrderInfo.objects.filter(user_id=uid).order_by('oIsPay', '-oid')
# print(type(orderinfos))
paginator = Paginator(orderinfos, 2)
page = paginator.page(int(pageindex))
context = {'page_name': 1, orderinfos': orderinfos, 'paginator': paginator, 'page': page}
return render(request, 'user_manage/user_center_order.html', context)
5.路由配置
urls.py
from django.conf.urls import url
from user_manage import views
urlpatterns = [
url(r'^register/$', views.register),
url(r'^register_handle/$', views.register_handle),
url(r'^login/$', views.login),
url(r'^login_handle/$', views.login_handle),
url(r'^logout', views.logout),
url(r'^info/$', views.info),
url(r'^order/$', views.order),
url(r'^user_order(\d+)/$', views.user_center_order),
url(r'^site/$', views.site),
]
6.装饰器,用来判断用户是否登录
login_decorator.py
from django.http import HttpResponseRedirect
# 用于需要登录才能访问的页面的装饰器
def login(func):
def login_dec(request, *args, **kwargs):
if 'user_id' in request.session: # 不支持request.session.has_key()方法
return func(request, *args, **kwargs)
else:
red = HttpResponseRedirect('/user/login/')
red.set_cookie('url', request.get_full_path()) # 保存完整路径,登录完可跳转回原页面
return red
return login_dec
到这里user-manage模块基本完成.