天天生鲜(Django4.0版本) + 开发遇到的问题及解决

目录

1、项目来源及开发介绍

1.1、天天生鲜介绍

1.2、Web开发流程介绍

1.2.1、需求分析

1.2.2、项目架构概览

1.2.3、SKU与SPU概念

2、项目架构

3、数据库表结构

4、用户认证模型

5、类视图

6、用户模块开发

6.1、Django4.0认证系统文档

6.2、用户注册

6.2.1、django发送邮件

 6.2.2、Celery异步任务队列

6.3、用户激活

6.3.1、加密用户身份信息

6.3.2、解密用户身份信息验证

6.4、用户登录

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

6.4.2、登录判断装饰器login_required

6.5、用户退出

6.6、用户地址

6.7、用户个人信息

6.7.1 redis存储历史浏览记录分析

6.7.2、django-redis获取redis链接

7、商品模块开发

7.1、了解FastDFS分布式文件系统

7.2、python对接fastdfs

7.3、项目上传图片和使用图片流程

7.4、Django二次开发对接FastDFS

7.5、商品首页

7.5.1、基本页面处理

7.5.2、保存购物车信息的数据设计

7.5.3 页面静态化

7.5.4、使用缓存

7.6、商品详情页

7.7、商品列表页

7.7.1、分页

7.7.2、页码控制

7.8、商品搜索

7.8.1、安装和配置

7.8.2、索引文件生成

7.8.3、全文检索的使用

7.8.4、改变分词方式

8、购物车模块开发

8.1、添加到购物车

8.2、购物车页面

8.3、购物车记录更新

8.4、购物车记录删除

9、订单模块开发

9.1、提交订单页面

9.2、订单生成

9.2.1、mysql事务

9.2.2、订单并发处理

9.3、用户中心-订单页

9.4、订单支付

10、项目部署

10.1、uwsgi

10.1.1、uwsgi的安装

10.1.2、uwsgi的配置

10.1.3、uwsgi的启动和停止

10.2、nginx

10.2.1、nginx 配置转发请求给uwsgi

10.2.2、nginx配置处理静态文件

10.2.3 nginx转发请求给另外地址

10.2.4、nginx配置upstream实现负载均衡

10.2.5、部署项目流程图

11、开发过程中遇到的bug个人总结

1、在模板中载入静态文件前需要在配置文件settings.py中加入配置

2、django新版本中查询数据库后对象不存在报错的异常类是core.exceptions的ObjectDoesNotExist

3、加密用户身份信息当做url的token值,用authlib包代替itsdangerous,可以指定签名算法HS256

4、celery不支持window10,安装eventlet包,使用celery -A celery_tasks.tasks worker -l info -P eventlet -E命令或者建议使用下面的命令就用安装eventlet包

5、django自带的login()报错:redis输入了一个空类型的值

6、Django的authenticate已经包含了is_active判断,即使用户名密码正确,is_active为0也会返回空,所以需要在setting.py中加配置

7、FastDFS只支持Linux,可以把fastDFS运行在云服务器上,Windows本地电脑上运行FastDFS客户端fdfs-client-py

8、window启动nginx,先到文件夹中启动nginx.exe,再到cmd中输入nginx.exe。停止nginx,在cmd中完整有序停止用nginx -s quit,再用taskkill /f /t /im nginx.exe

9、is_authenticated在Django4.0中是一个属性而不是一个方法

10、Django4.0已经移除ungettext,所以在引入haystack的时候会报错,修改haystack文件夹下的admin.py把ungettext三处地方修改为ngettext

11、Django4.0已经移除smart_text,修改haystack文件夹下的form.py俩处地方把smart_text修改为smart_str

12、配置为乐观锁时,需要设置MySQL默认的隔离级别(可重复读)为(读取提交内容),在MySQL配置文件skip-ex,,,下添加一行transaction-isolation = READ-COMMITTED

13、网站如果想让支付宝平台访问(获取支付后的结果),需要有公网IP

14、安装alipay-sdk-python 提示安装pycrypto 问题:

15、支付宝沙箱测试不需要重新设置密钥和公钥,直接使用默认。

16、使用支付宝交易查询接口要使用AlipayTradeQueryResponse来获取解析后响应的结果

17、win10上没法部署uwsgi,可以通过其它方式间接使用uwsgi,但没必要,最终都是要部署在Linux系统。

18、Django网站响应慢(修改数据库查询方式)

19、指定表名,不用一定和应用名相连,class Meta:  db_table = '表名'

20、发布网站时需要在settings.py中把debug改为false,allowed_host = ['*']

21、cookie:是由服务器生成,存储在浏览器端的一小段文本信息。

22、session

23、模板中的自定义过滤器参数只能是一个或俩个

24、csrf防护(跨站请求伪造攻击):

25、url反向解析:


1、项目来源及开发介绍

修改后的天天生鲜(Django4.0版本):

GitHub - LiXZe/dailyfreshContribute to LiXZe/dailyfresh development by creating an account on GitHub.https://github.com/LiXZe/dailyfresh

1.1、天天生鲜介绍

    首先,此次天天生鲜项目来源是黑马程序员Python就业班的Web开发项目,虽是几年前的项目,但在Python商城项目里也算是功能比较齐全,什么异步任务处理、页面静态化、搜索引擎、高并发库存问题、邮件发送激活、购物车缓存、分布式文件存储、服务器部署、支付宝支付接口调用这些都有,适合拿来学习Python的Web开发练练手,此篇博客的内容也是我对原先项目笔记的修改,有些图片是原先黑马项目的图片。

    其次,原先天天生鲜项目使用的是Django1.8.2版本,我自己改成了新版本Django4.0版本的,使用的虚拟环境是anaconda,不论学习什么语言和框架,一定要会看框架对应的开发文档,从1.8.2到4.0版本的变动挺多的,就需要自己去查看Django4.0的开发文档,附上Django4.0中文的开发文档对应链接:

Django 文档 | Django 文档 | Djangohttps://docs.djangoproject.com/zh-hans/4.0/

    最后文末,是我在开发过程中遇到的各种问题,然后我就记了下来,附上了我的解决方法(由于我这个项目是在win10环境下写的,所以遇到的问题会更多。

先上网站运行后截图:

首先是主页:

用户中心的3个功能页面:

 

 

 

 购物车页面:

 

订单支付:

 

商品详情:

 

 

 

1.2、Web开发流程介绍

在正式学习商城项目开发前,先介绍一下常见Web商城项目的开发流程:

1.2.1、需求分析

1.2.1.1、用户模块

1.注册页

  • 注册时校验用户名是否已被注册。
  • 完成用户信息的注册。
  • 给用户的注册邮箱发送邮件,用户点击邮件中的激活链接完成用户账户的激活。

2.登录页

  • 实现用户的登录功能。

3.用户中心

  • 用户中心信息页:显示登录用户的信息,包括用户名、电话和地址,同时页面下方显示出用户最近浏览的商品信息。
  • 用户中心地址页:显示登录用户的默认收件地址,页面下方的表单可以新增用户的收货地址。
  • 用户中心订单页:显示登录用户的订单信息。

4.其他

  • 如果用户已经登录,页面顶部显示登录用户的信息。

1.2.1.2、商品相关

1.首页

  • 动态指定首页轮播商品信息。
  • 动态指定首页活动信息。
  • 动态获取商品的种类信息并显示。
  • 动态指定首页显示的每个种类的商品(包括图片商品和文字商品)。
  • 点击某一个商品时跳转到商品的详情页面。

2.商品详情页

  • 显示出某个商品的详情信息。
  • 页面的左下方显示出该种类商品的2个新品信息。

3.商品列表页

  • 显示出某一个种类商品的列表数据,分页显示并支持按照默认、价格、和人气进行排序。
  • 页面的左下方显示出该种类商品的2个新品信息。

4.其他

  • 通过页面搜索框搜索商品信息。

1.2.1.3、购物车相关

  • 列表页和详情页将商品添加到购物车。
  • 用户登录后,首页,详情页,列表页显示登录用户购物车中商品的数目。
  • 购物车页面:对用户购物车中商品的操作。如选择某件商品,增加或减少购物车中商品的数目。

1.2.1.4、订单相关

  • 提交订单页面:显示用户准备购买的商品信息。
  • 点击提交订单完成订单的创建。
  • 用户中心订单页显示用户的订单信息。
  • 点击支付完成订单的支付。

1.2.2、项目架构概览

1.2.2.1、页面图:

1.2.2.2、功能图:

1.2.2.3、部署图:

1.2.3、SKU与SPU概念

    SPU = Standard Product Unit (标准产品单位)

    SPU 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述 了一个产品的特性。通俗点讲,属性值、特性相同的商品就可以称为一个 SPU。 例如:iphone7 就是一个 SPU,与商家,与颜色、款式、套餐都无关。

    SKU=stock keeping unit(库存量单位)

    SKU 即库存进出计量的单位, 可以是以件、盒、托盘等为单位。 SKU 是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。 在服装、鞋类商品中使用最多最普遍。 例如:纺织品中一个 SKU 通常表示:规格、颜色、款式。

2、项目架构

3、数据库表结构

4、用户认证模型

5、类视图

将视图view以类的形式定义

通用类视图基类:

django.views.generic.View  ( 与django.views.generic.base.View 是同一个)

urls.py中配置路由使用类视图的as_view()方法

由dispatch()方法具体将请求request分发至对应请求方式的处理方法中(get、post等)

类视图资料:内置基于类的视图 API | Django 文档 | Django

6、用户模块开发

6.1、Django4.0认证系统文档

django-admin 和 manage.py | Django 文档 | Django

方法名

备注

create_user

创建用户

authenticate

登录验证

login

记录登录状态

logout

退出用户登录

is_authenticated

判断用户是否登录

login_required装饰器

进行登录判断

6.2、用户注册

6.2.1、django发送邮件

 6.2.2、Celery异步任务队列

6.2.2.1、使用

在项目根目录下新建一个celery_task文件夹,文件夹下新建一个task文件:

# 使用celery
from django.core.mail import send_mail
from django.conf import settings
from celery import Celery
import time
from django.template import loader

# 在任务处理者一端加这几句
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings")
django.setup()

from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner

# 创建一个Celery类的实例对象
app = Celery('celery_tasks.tasks', broker='redis://mast:yourpassword@127.0.0.1:6379/1')  # 使用我本地电脑的redis的1号数据库当做celery的broker,

此段代码在注册视图函数中,异步实现发送邮件功能:

# 发送激活邮件,包含激活链接: http://127.0.0.1:8000/user/active/token值
        # 激活链接中需要包含用户的身份信息, 并且要把身份信息进行加密

        """加密用户的身份信息,生成激活token,使用authlib代替itsdangerous"""
        data = {'confirm': user.id}
        header = {'alg': 'HS256'}  # 签名算法
        token = jwt.encode(header=header, payload=data, key=settings.SECRET_KEY)  # byte类型
        token = token.decode()

        # 发送邮箱:使用celery异步处理发送邮件,加入到任务队列(broker)中
        send_register_active_email.delay(email, username, token)

        # 返回应答, 跳转到首页
        return redirect(reverse('goods:index'))

6.2.2.2、发出任务

6.2.2.3、启动worker

重新打开一个终端,输入命令celery -A celery_tasks.tasks worker -l info --pool solo

6.3、用户激活

使用authlib加密用户的身份信息,而不是使用原先项目自带的itsdangerous。

authlib的使用:

参考资料:

JSON Web Token (JWT) — Authlib 1.0.1 documentation

6.3.1、加密用户身份信息

from authlib.jose import jwt, JoseError


"""加密用户的身份信息,生成激活token,使用authlib代替itsdangerous"""
    data = {'confirm': user.id}
    header = {'alg': 'HS256'}  # 签名算法
    token = jwt.encode(header=header, payload=data, key=settings.SECRET_KEY)  # byte类型
    token = token.decode()

6.3.2、解密用户身份信息验证

# 进行解密,获取要激活的用户信息
    try:
        info = jwt.decode(token, settings.SECRET_KEY)
        print(info)
        # 获取待激活用户的id
        user_id = info['confirm']

        # 根据id获取用户信息
        user = User.objects.get(id=user_id)
        user.is_active = 1
        user.save()

6.4、用户登录

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

django-redis文档:django-redis 中文文档 — Django-Redis 4.7.0 文档

配置:

# Django的缓存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",  # 使用2号数据库
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "PASSWORD": "yourpassword"
        }
    }
}

6.4.2、登录判断装饰器login_required

可以在用户模块的地址配置直接使用:

urlpatterns = [
    path('register/', RegisterView.as_view(), name='register'),  # 使用视图类
    re_path(r'active/(?P<token>.*)$', ActiveView.as_view(), name='active'),  # 激活用户
    path('login/', LoginView.as_view(), name='login'),

    path('', UserInfoView.as_view(), name='user'),  # 用户信息-中心
    re_path(r'order/(?P<page>\d+)$', UserOrderView.as_view(), name='order'),  # 用户信息-订单
    path('address/', AddressView.as_view(), name='address'),  # 用户信息-地址
    path('logout/', LogoutView.as_view(), name='logout'),  # 用户注销
    path('testcelery/', views.testCelery)

    # path('', login_required(UserInfoView.as_view()), name='user'),  # 用户信息-中心
    # path('order/', login_required(UserOrderView.as_view()), name='order'),  # 用户信息-订单
    # path('address/', login_required(AddressView.as_view()), name='address'),  # 用户信息-地址
    # path('register', views.register, name='register'),
    # path('register_handle', views.register_handle, name='register_handle')
]

或者修改类LoginRequireMixin中的父类的as_view方法:

在setting.py中配置未登录时的跳

6.5、用户退出

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

6.6、用户地址

模型类和模型管理器类:

6.7、用户个人信息

6.7.1 redis存储历史浏览记录分析

 

参考资料:

Redis 命令参考 — Redis 命令参考

Welcome to redis-py’s documentation! — redis-py dev documentation

6.7.2、django-redis获取redis链接

from django_redis import get_redis_connection


on = get_redis_connection('default')  # 使用setting.py中默认的redis配置

7、商品模块开发

7.1、了解FastDFS分布式文件系统

(我个人是把FastDFS部署在自己的阿里云服务器上,安装到云服务器上去访问是也遇到了很多问题,文末总结问题)

集群

启动FastDFS的方法,需要的操作:

修改如下的配置文件  (在/etc/fdfs目录中)

 

tracker_server=己的ip:22122

启动tracker、storage、nginx服务:

sudo service fdfs_trackerd start

sudo service fdfs_storaged start

sudo /usr/local/nginx/sbin/nginx

执行如下命令测试是否成功

fdfs_upload_file /etc/fdfs/client.conf 要上片文件

如果返回类似group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg的文件id则

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值