天天生鲜项目经验

一、项目架构

前端:

  • 用户相关
  • 商品相关
  • 购物车相关
  • 订单相关
  • 后台管理

后端:

  • 用户模块
  • 商品模块
  • 购物车模块
  • 订单模块
  • 后台管理模块

技术:

  • mysql
  • session 缓存服务器redis
  • 异步任务处理celery
  • 分布式文件存储系统fastdfs

二、用户认证模型

# django认证系统使用的用户模型
AUTH_USER_MODEL = "users.User"

1.类视图

将视图view以类的形式定义,通用类视图基类:
django.views.generic.View
urls.py中配置路由使用类视图的as_view()方法,由dispatch()方法具体将请求request分发至对应请求方式的处理方法中(get、post)等

2.django认证系统

方法名 备注
create_user 创建用户
authenticate 登录验证
login 记录登录状态
logout 退出用户登录
is_authenticated 判断用户是否登录
login_required装饰器 进行登录判断

3.django发送邮件

Django网站---->smtp服务器----->目的邮箱

SMTP的全程是Simple Mail Transfer Protocol,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送获中转信件时找到下一个目的地,SMTP服务器就是遵循SMTP协议的发送邮件服务器,不同邮件服务商均有对应的smtp服务器地址,并且这个地址会提供给大家,方便大家使用Foxmail与outlook等专业邮件管理软件时可以用得上。

4.celery:异步任务队列

任务的发出者、中间人、任务的处理者可以在同一台电脑上启动,也可以不在同一台电脑上。处理者也需要任务的代码,任务处理者所在电脑必须有网

pip install celery

项目代码(任务发出者)
—发出任务—>
任务队列(中间人broker)redis
<—监听任务队列—任务处理者worker
1)使用

from celery import Celery
# 创建一个Celery类的实例对象
app = Celery('celery_tasks.tasks', broker='redis://172.16.179.130:6379/8')

2)发出任务

@app.task
def send_register_active_email(to_email, username, token):
	# 发送邮件的代码
	pass
	
# 发邮件:此方法会把发邮件的任务放到任务队列中
send_register_active_email.delay(email, username, token)

3)启动worker

celery -A celery_tasks.tasks worker -l info

5.用户激活

使用itsdangerous加密用户身份信息
1)加密码用户身份信息

# 加密用户的身份信息,生成激活token
serializer = Serializer(settings.SECRET_KEY, 3600)
info = {'confirm':user.id}
token = serializer.dumps(info)
token = token.decode()

2)解密用户身份信息

serializer = Serializer(settings.SECRET_KEY, 3600)
try:
	# 根据秘钥解密
	info = serializer.loads(token)
	# 获取待激活用户的id
	user_id = info['confirm']
	# 根据id获取用户信息
	user = User.objects.get(id=user_id)
	user.is_active = 1
	user.save()
	# 跳转到登录页面
	return redirect(reverse('user:login'))
except SignatureExpired as e:
	return HttpResponse('激活连接已过期!')

6.用户登录

6.1 配置redis作为Django缓存和session后端

配置:

# Django的缓存配置
CACHES = {
	"default":{
		"BACKEND": "django_redis.cache.RedisCache",
		"LOCATION": "redis://172.16.179.142:6379/9",
		"OPTIONS":{
			"CLIENT_CLASS":"django_redis.client.DefaultClient",
	}
	}
}
# 配置sessiong存储
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
6.2 登录判断装饰器loging_required

使用LoginRequireMixin:

from django.contrib.auth.decorators import login_required

class LoginRequiredMixin(object):
	@classmethod
	def as_view(cls, **initkwargs):
		# 调用父类的as_view
		view = super(LoginRequiredMinxin, cls).as_view(**initkwargs)
		return login_required(view)

登录后跳转

# 获取登录后所需要跳转的地址
# 默认跳转到首页
next_url = request.GET.get('next', reverse('goods:index'))
# 跳转到next_url
response = redirect(next_url) # 重定向到新的地址
6.3 用户退出

logout 函数清楚登录用户的session信息

6.4 django-redis获取redis连接
from django_redis import get_redis_connection

con = get_redis_connection('default')

商品模块开发

1. 了解FastDFS分布式文件系统

集群
启动FastDFS的方法,需要的操作

  1. 修改如下的配置文件(在/etc/fdfs目录中)
    在这里插入图片描述
    tracker_server = ip地址:22122
  2. 启动tracker、storage、nginx服务:
sudo service fdfs trackerd start
sudo service fsfs storaged start
sudo /usr/local/nginx/sbin/nginx
  1. 执行如下命令测试是否成功
fdfs_upload_file /etc/fdfs/client.conf 要上传的图片文件

2.python对接fastdfs

  1. workon django_py3
  2. 进入fdfs_client-py-master.zip所在目录
  3. pip install fdfs_client-py-master.zip

3.项目上传图片和使用图片流程

海量存储,存储容量扩展方便。
文件内容重复时只保留一份。
结合nginx提高网站访问图片的效率
天天生鲜项目经验_第1张图片

4. Django二次开发对接FastDFS

  1. 配置文件settinggs中加入如下配置
# 配置文件存储类
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FDFSStorage'

# 配置fdfs客户端配置文件路径
FDFS_CLIENT_CONF = './utils/fdfs/client.conf'
FDFS_SERVER_URL='http://172.16.179.131:8888/'
  1. 创建utils/fdfs目录
    天天生鲜项目经验_第2张图片
  2. storage.py文件中自定义文件存储类
    天天生鲜项目经验_第3张图片

三、商品首页

  1. redis保存用户的购物车记录
    采用的数据形式:每个用户的购物车记录用一条数据保存:
    hash:
    cart_用户id:{‘SKU_ID1’:数量,‘sku_id2’:数量}
  2. 页面静态化
    把原本动态的页面处理结果保存成html文件,让用户直接访问这个生成出来的静态的html页面
    ①使用celery生成静态页面
    ②配置nginx提供静态页面
    ③管理员修改首页所使用表中的数据时,重新生成index静态页面
  3. 商品搜索
    搜索引擎:
    1)可以对表中的某些字段进行关键词分析,简历关键词对应的索引数据。
    索引:字典目录
    全文检索框架:可以帮助用户使用搜索引擎。
    用户----》全文检索框架haystack-----》搜索引擎whoosh
    2) 搜索引擎的安装和配置
    ①安装python包:
pip install django-haystack
pip install whoosh

②在settings.py文件中注册应用haystack并做如下配置:

INSTALLED_APPS = (
	'haystack', # 全文检索框架
)
.
.
.
.
# 全文检索框架的配置
HAYSTACK_CONNECTIONS = {
	'default':{
		# 使用whoosh引擎
		'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
		'PATH': os.path.join(BASE_DIR, 'whoosh_index')
	}
}

# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
  1. 索引文件生成
    ①在goods应用目录下新建一个serach_indexes.py文件,在其中定义一个商品索引类。
class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
	'''商品索引类'''
	text = indexes.CharField(document=True, use_template=True)

	def get_model(self):
		return GoodsSKU
	def index_queryset(self, using=None):
		return self.get_model().objects.all()

②在templates下面新建目录search/indexes/goods
天天生鲜项目经验_第4张图片
③在此目录下面新建一个文件goodssku_text.txt并编辑内容如下

# 制定索引的数据行
{{ object.name }}
{{ object.desc }}
{{ object.goods.detail }}

④ 使用命令生成索引文件
python manage.py rebuild_index

四、订单

mysql事务

  1. 事务的概念:一组mysql语句,要么执行,要么全部执行
  2. 事务的特点:
  • 原子性:一组事务,要么成功,要么撤回
  • 稳定性:有非法数据(外键约束之类),事务撤回
  • 隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度
  • 可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit选项,决定什么时候把事务保存到日志里
  1. 事务控制语句
  • BEGIN/START TRANSACTION:显式地开启一个事务
  • COMMIT,也可以用COMMIT WORK,提交事务
  • ROLLBACK,也可以用ROLLBACK WORK,回滚,撤销正在运行的所有未提交的修改。
  • SAVEPOINT identifier;允许在事务中创建一个保存点
  • RELEASE SAVEPOINT identifier;删除一个事务的保存点
  • ROLLBACK TO identifier;把事务回滚到标记点
  1. mysql事务隔离级别
    SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
  • Read Uncommitted(读取未提交内容)
    在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能不比其他级别好多少。读取未提交的数据,也被称之为脏读

脏读:某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

  • Read Committed(读取提交内容)
    这是大多数数据库系统的默认隔离级别(但不是mysql默认的)。它满足了隔离的简单定义:一个事务智能看见已提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同结果

不可重复读(Non-replacetable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原油的数据。

  • Repeatable Read(可重读)
    这是mysql的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了该问题。

幻读(Phantom Read):在一个事务的两次查询中数据不一致,例如有一个事务查询了几行数据,而另一个事务却在此时插入了新的几行数据,先前的事务在接下来的查询中,就会发现有几行数据是它先前所没有的。

  • Serializable(可串行化)
    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。这个级别,可能导致大量的超时现象和锁竞争。
    天天生鲜项目经验_第5张图片
  1. 设置mysql事务的隔离级别
    打开mysql配置文件:sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    天天生鲜项目经验_第6张图片
    保存配置文件,重启mysql服务:sudo service mysql restart

订单并发处理

多个用户同事请求数据库
(1)悲观锁
select * from df_goods_sku where id = 17 for update;
悲观锁获取数据时对数据进行了锁定,其他事务要想获取锁,必须等原事务结束。
(2)乐观锁
查询时不锁数据,提交更改时进行判断
update df_goods_sku set stock=0,sales=1 where id=17

冲突比较少的时候,使用乐观锁
冲突比较多的时候,使用悲观锁

五、项目部署

1.uwsgi

遵循wsgi协议的web服务器

  1. uwsgi的安装
    pip install uwsgi
  2. uwsgi的配置
    项目部署时,需要把settings.py文件夹下的:
DEBUG=FALSE
ALLOWED_HOSTS=P['*']
[uwsgi]
#使用nginx连接时使用
#socket=127.0.0.1:8080
#直接做web服务器使用
http=127.0.0.1:8080
#项目目录
chdir=/Users/smart/Desktop/dj/bj17/dailyfresh
#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=dailyfresh/wsgi.py
processes=4
threads=2
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log
virtualenv=/Users/smart/.virtualenvs/dailyfresh
  1. uwsgi的启动和停止
  • 启动:uwsgi–ini 配置文件路径,例如:uwsgi–ini uwsgi.ini
  • 停止:uwsgi–stop uwsgi.pid路径,例如:uwsgi–stop uwsgi.pid

2.nginx

  1. nginx配置转发请求给uwsgi
location/{
	include uwsgi_params;
	uwsgi_pass_uwsgi服务器的ip:port
}
  1. nginx配置处理静态文件
    django settings.py中配置收集静态文件路径:
    STATIC_ROOT=收集的静态文件路径 例如:/var/www/dailyfresh/static;

django 收集静态文件的命令:
python manage.py collectstatic
执行上面的命令会把项目中所使用的静态文件收集到STATIC_ROOT指定的目录下。

收集完静态文件之后,让nginx提供静态文件,需要在nginx配置文件中增加如下配置:
location /static {
alias /var/www/dailyfresh/static/;
}

  1. nginx转发请求给另外的地址
    在location对应的配置项中增加proxy_pass转发的服务器地址。
    如:当用户访问127.0.0.1时,在nginx中配置把这个请求转发给172.16.179.131:80(nginx)服务器,让这台服务器提供静态首页。
    location = /{
    proxy_pass http://172.16.179.131;
    }
    9.2.4 nginx配置upstream实现负载均衡
    ngnix 配置负载均衡时,在server配置的前面增加upstream配置项。
    upstream dailyfresh {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    }
  2. 部署项目流程图
    天天生鲜项目经验_第7张图片

你可能感兴趣的:(python)