每日生鲜-Django实现
功能模块

数据库结构设计

用户表和地址表是一对多的关系
1、把model类搞定
2、完成登陆注册功能
django富文本编辑器
pip install django-tinymce==2.6.0
# 富文本编辑器配置
```python
TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 600,
'height': 400,
}
报错
'Specifying a namespace in include() without providing an app_name '
改成
url文件中: path('^user/',include(('user.urls','user'),namespace='user')),
生成表结构

注册功能
1、接收数据
2、进行数据校验
3、进行业务处理
4、返回应答
激活邮件:需要包含用户信息并且加密(token)
itsdangerous加解密数据
pip install itsdangerous
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
serializer = Serializer('secretkey', 3600)
info = {'confirm',1}
result = serializer.dumps(info)
serializer.dumps(info)
django邮件发送
535, b'Login Fail. Please enter your authorization code to login
配置文件中改成独立授权码
celery异步发送邮件


任务处理者启动
celery -A celery_tasks.tasks worker -l info

任务处理者加入Django环境初始化

配置cache和session到redis中
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/9",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
记住用户名
response.set_cookie()
response.delete_cookie()
登陆后跳转到刚才的页面
Form表单,action不指定时,默认向当前url提交数据
Django会自动创建一个request.user对象,返回到模板文件
- 如果用户登陆,
user是User类的一个实例 - 如果用户未登录,
user是AnnoymouseUser的实例
封装模型操作类,自定义模型操作方法
历史浏览记录
1、访问商品详情页的时候添加浏览记录
2、访问用户中心的时候获取浏览记录
用redis的list数据类型存储浏览记录,从列表左侧插入最新的浏览数据
FastDFS分布式文件存储系统
提供文件上传和下载服务
Tracker server调度
Storage server 存储
优点:海量存储,扩展方便,同样内容的文件只存储一份,如果上传相同的文件,会直接返回,不需要上传
安装依赖包libfastcommon
#依赖包
git clone https://github.com/happyfish100/libfastcommon.git
./make.sh
.make.sh install
安装fastdfs
git clone https://github.com/happyfish100/fastdfs.git
./make.sh
.make.sh install
配置跟踪服务器tracker
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
mkdir -p ~/fastdfs/tracker
vim /etc/fdfs/tracker.conf
base_path = ~/fastdfs/tracker
配置存储服务器storage
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
mkdir -p ~/fastdfs/storage
vim /etc/fdfs/storage.conf
base_path = ~/fastdfs/storage
store_path0 = ~/fastdfs/storage
tracker_server = 127.0.0.1:22122
启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
测试安装成功
# 配置客户端
cp /etc/fdfs/cilent.conf.sample /etc/fdfs/cilent.conf
vim /etc/fdfs/cilent.conf
base_path = ~/fastdfs/tracker
tracker_server = 127.0.0.1:22122
# 上传文件
fdfs_upload_file /etc/fdfs/client.conf 1.png
报错

查看日志

strack ip不能设置成127.0.0.1,换成本机ip解决问题
安装nginx和fastdfs-nginx-module
用户量大的时候处理高并发
wget http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz
git clone https://github.com/happyfish100/fastdfs-nginx-module.git
# 编译安装nginx
./configure --prefix=/usr/local/nginx --add-module=/media/zhkai/Data/java/fastdfs-nginx-module/src
make && make install
# 配置文件mod_fastdfs.conf
cp fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
connect_timeout=10
tracker_server=192.168.0.9:22122
url_have_group_name = true
store_path0=/home/zhkai/fastdfs/storage
cp fastdfs/conf/http.conf /etc/fdfs/
cp fastdfs/conf/mime.types /etc/fdfs/
# 编辑nginx配置文件
vim /usr/local/nginx/conf/nginx.conf
server {
listen 8888;
server_name localhost;
location ~/group[0-9]/{
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 启动nginx
/usr/local/nginx/sbin/nginx
/usr/local/nginx/sbin/nginx -s stop
fastdfs与python交互
pip install fdfs_client-py-1.2.6.tar.gz #python2
pip install py3fds #python3

网站性能优化
首页页面的静态化(celery)
通过nginx访问静态文件,admin中每次修改数据时更新静态页面

页面数据缓存,减少数据库查询次数
from django.core.cache import cache
cache.set(key, value, timeout)
cache.get(key)
购物车添加到redis
1、添加购物车数据,
2、获取购物车记录
3、存储购物车记录的格式hash user_id:number
添加浏览记录到redis
对列表页控制
1、总页数小于5页,显示所有页码
2、当前页是前3页,显示1-5页
3、当前页是后3页,显示后5页
4、其他情况,显示当前页的前2页,和后2页
商品搜索
搜索引擎:对表中的字段进行关键词分析,并建立对应的索引
全文检索框架:帮助用户使用搜索引擎
pip install django-haystack
pip install whoosh
pip install jieba
setting配置
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
# 添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
索引文件生成
在goods应用下创建search_indexes.py

mkdir templates/search/indexes/goods
touch goodssku_text.txt

python manage.py rebuild_index
返回结果

django3.x 使用haystack 报错:ImportError: cannot import name 'six' from 'django.utils'
修改whoose默认分词为jieba
pip install jieba
cd haystack/backends
touch ChineseAnalyzer.py
cp whoosh_backend.py whoosh_cn_backend.py
vim !$
ChineseAnalyzer.py
import jieba
from whoosh.analysis import Tokenizer, Token
class ChineseTokenizer(Tokenizer):
def __call__(self, value, positions=False, chars=False,
keeporiginal=False, removestops=True,
start_pos=0, start_char=0, mode='', **kwargs):
t = Token(positions, chars, removestops=removestops, mode=mode,**kwargs)
seglist = jieba.cut(value, cut_all=True)
for w in seglist:
t.original = t.text = w
t.boost = 1.0
if positions:
t.pos = start_pos + value.find(w)
if chars:
t.startchar = start_char + value.find(w)
t.endchar = start_char + value.find(w) + len(w)
yield t
def ChineseAnalyzer():
return ChineseTokenizer()
修改settings文件
重新生成索引
添加购物车
1、请求方式,ajax
- 如果涉及到表数据的修改,采用
post - 如果只涉及到数据的获取,采用
get
2、传递参数:商品id 商品数量
订单模块
事务:一组mysql语句,要么执行,要么不执行
事务控制语句:
开启事务:BEGIN,START TRANSACTION
提交:COMMIT
回滚:ROLLBACK
Django使用mysql事务
from django.db import transaction
mysql对表数据修改时,会进行锁表,两个修改语句不能同时进行
并发:操作系统内在同一个CPU上同时运行的进程
数据库并发:同一时间内不同进程对相同数据做了操作,用户读取到脏数据
数据库并发问题处理
1、悲观锁,
在查询时加锁,其他用户需要等到锁释放后,才能执行查询操作,也就是阻塞;拿到锁的用户才会操作
select * from table_name where id=1 for update;
2、乐观锁,查询数据的时候不加锁
在更新时进行判断,判断更新时的库存和之前查询的库存是否一致
mysql事务隔离级别
1、默认隔离级别Repeatable Read可重读,保证一个事务的多个实例读取并发时保证读取相同的数据,会导致幻读,两次查询读取到的数据不一致
2、级别2,读取提交内容Read Committed,大多数数据库系统的默认隔离级别。一个事务只能看见已经提交的事务所作的改变。支持不重复读
修改日志事务级别
vim my.cnf
transaction-isolatin = READ-COMMITED
在冲突比较少的时候,使用乐观锁
乐观锁重复操作的代价比较大,使用悲观锁
接入支付宝

return_url :用户点击之后时同步跳转的地址
notify_url:用户点击支付后异步返回支付结果,所以异步结果更准确
沙箱环境
接口文档
非官方支付宝 Python SDK
https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
错误排查

同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。 同步过程返回的
异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。
模板文件
{% for i in item %}
{{ forloop.counter }} 表示当前迭代数(第几次循环)从1开始
{% endfor %}
完整代码地址:

浙公网安备 33010602011771号