# Django_shop **Repository Path**: me-dont-want-to-write-code/django_shop ## Basic Information - **Project Name**: Django_shop - **Description**: 基于Django框架实现的运动商城系统,python课程设计 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 6 - **Created**: 2024-12-10 - **Last Updated**: 2024-12-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前言 > 这是一个Java里Java气的`django`项目,有熟悉的bean实体类(在models.py),有dao用于数据库操作(在dao.py) - 本项目前后端进行了分离,前端使用vue实现,并且前端代码已经打包好放在`static`目录下 - 后端使用django的views.py来制作api接口,具体请求接口可以查看`API接口文档.md` > 环境要求:MySQL 8、python3.11、django4.2、pymysql # 如何运行 ## 1、下载本项目到你的电脑后解压 ![下载](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6/img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20005530.png) ## 2、附加数据库 将根目录下的 `sports_shop.sql` 附加到你的mysql中 ![附加数据](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20005814.png) ### 3、修改数据库连接语句 在`sports_shop_backend_war/dao.py`文件中,将登录名和密码修改为你mysql的配置 ![修改数据库连接语句](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20010056.png) ### 4、pip安装所需的库 一共有如下两个个: - `pip install django==4.2` - `pip install pymysql` ### 5、运行项目 前端已经写死了请求后端api的基准地址为`http://127.0.0.1:8888` 因此需要切到 `项目根目录` 执行如下命令: ```shell python .\manage.py runserver 8888 ``` 然后,就可以项目就跑起来了 ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20011718.png) # 效果总览 ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20011853.png) ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20011949.png) ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20012035.png) ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20012112.png) ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20012148.png) ![运行](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6//img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-05-04%20012225.png) # 如何入手 - static 文件夹是前端打包过后的代码,具体前端代码可以移步:https://gitee.com/kang-zhenbin/sports_shop_front - django_shop是项目,sports_shop_backend_war是app。一下讲的都是app - models.py里面编写了对应数据库表的实体类 - dao.py里面编写了数据库连接方法,已经对应表的增删改查操作 - urls.py和views.py以及service.py 一起完成了api的逻辑 - 其中urls.py是请求的路由分发逻辑 - views.py和service.py完成了api逻辑实现 # 踩坑记录 ### 2023/4/25 django自带的ORM对mysql进行增删改查很奇怪,会给你的数据库生成一大堆表(似乎帮你搞好了一个后台管理系统) 与spring开发并不相同,没法用实体类对应数据库表的习惯来理解这东西 Template 这东西并不能挂载静态资源 得用static来挂载静态资源,默认访问路径是 `ip+端口号/static/xxx` ### 2023/4/26 挂载vue打包后的静态文件,只需在urls.py的urlpatterns中添加一行: ```path('', RedirectView.as_view(url='/static/index.html', permanent=False), name='index'),``` ### 2023/4/27 python这语言简直是非主流,当你习惯了主流C,Java,JavaScript之类的语言,再来写python,简直要世界观崩塌 关于实体类: - 1.文件名也算名,并不是文件名与类名一致就可以了。导入的时候要 `entity.User.User` 是的,第一个是文件名,第二个是类名 - 2.如果你的项目分了多个子目录,比如dao、entity、util。那么你想要在dao中调用entity,你还得用`sys.path.appedn()`去拼接路径 - 3.如果你要调用一个python文件中的类,然后这个文件的类又引用了其他文件的类,你还得改这个文件的类import的路径,去迎合最大的那个调用类。。。。。amazing - 4.在python中定义一个类 简直就是依托答辩。。。。 ### 2023/4/27 不错不错,逐渐适应了这个语言 django现在暂时只用来挂载我vue打包好的静态页面,默认进入`loclahost:8000`的时候,自动路由跳转到`localhost:8000/static/index.html` 在django_shop项目下,有一个名为sports_shop_backend_war的app 这个app里面目前主要编写的文件夹和文件有 - dao文件夹 - entity文件夹 - test.py entity里面是实体类 dao里面是一些未来service将要用到的数据库操作 test.py用来测试写好的代码,已经测了各个实体类,还有一些XxxDaoImpl类下的方法 ### 2023/4/28 由于python奇葩的导包机制,比如 ```shell ¬父级目录∨: urls.py views.py ¬dao文件夹∨: UserDao.py OrderDao.py Shopping_cartDao.py GoodDao.py CommentDao.py Mini_Shopping_cartDao.py ¬entity文件夹∨: User.py Order.py Shopping_cart.py Good.py Comment.py Mini_Shopping_cart.py ``` 然后, 我在那些dao操作的类中,引用了entity文件夹里面的实体类 ```python from entity.User import User ``` 我在那些service操作的类中,引用了dao文件夹里面的dao数据访问类 ```python from dao.UserDao import UserDaoImpl ``` 最后, 我在views.py开始编写后端网络api请求: ```python from django.http import HttpResponse, JsonResponse from django.shortcuts import render # 服务层 from .service.UserService import UserService # Create your views here. def index(request): return HttpResponse('欢迎测试') # 登录API def login(request): username = request.POST.get('username') password = request.POST.get('password') return JsonResponse(UserService().login(username,password)) ``` 在urls.py绑定请求路径: ```python # app/urls.py from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), path("login", views.login, name="login") ] ``` 一通操作猛如虎,一开测试凉凉 ![错误示范](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6/img/%E9%94%99%E8%AF%AF%E7%A4%BA%E8%8C%83.png) ![错误示范](/sports_shop_backend_war/%E8%88%8D%E4%B8%8D%E5%BE%97_%E5%AE%9D%E8%B4%9D%E5%9E%83%E5%9C%BE%E6%A1%B6/img/%E5%AF%BC%E5%8C%85%E6%8A%A5%E9%94%99%E4%BF%A1%E6%81%AF.png) 最后的解决办法只能是: - 把实体类一股脑粘贴到models.py文件内 - 把dao数据访问类一股脑粘贴到models.py同级的dao.py文件内 这个时候在回来写`views.py`,`urls.py`作为control ### 2023/4/29 #### 关于多个类存进字典再转换成JSON数据 ```python def login (self,username:str,password:str): '''通过用户ID查询用户信息 @param 用户名, @param 密码, @return {User+Meta} 字典数据''' user_id = UserDaoImpl().selectByNamePWD(username,password) data = UserDaoImpl().selectByID(user_id) meta = Meta("登录成功",200) response = { 'data': data, 'meta': meta } json_str = json.dumps(response, default=lambda o: o.__json__() if isinstance(o, (User, Meta)) else None, ensure_ascii=False) print(json_str) return (json_str) ``` #### 关于获取AJAX发送过来的POST数据 request.POST.GET('XXX')无法使用 先把request.body 用json转换出来,在.get('XXX')也不行 打印request.POST 打印 request.body 啥也没有 翻了大半天资料找不出方法 最后死马当活马医,瞎写用request.GET.GET('XXX')就可以,这就很神奇 ```python def login(request): username = request.GET.get('username') password = request.GET.get('password') print(request.body) # print("=============================") # concat = request.POST # postBody = request.body # print(concat) # print(type(postBody)) # print(postBody) # json_result = json.loads(postBody) # print(json_result) return HttpResponse(UserService().login(username,password),content_type="application/json") ``` ### 2023/5/4 #### 如何进行接受上传的文件 使用 `request.FILES.get('表单name')` 即可获取到上传过来的文件 - 其中`request.FILES.get('表单name').name`可以获取到文件名 - `request.FILES.get('表单name').read()`可以读取文件的二进制数据流 #### 如何保存到目标目录下 千万别去导入什么 项目名.settings的BASE_DIR 这玩意导进来空空如也 你只需要这样操作 一行获取当前项目的位置 `BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))` 再来一行拼接到文件目标位置 `upload_path = BASE_DIR + '/static/picture/'+fileName` 千万别搞什么os.path.join()来拼接路径,你的BASE_DIR会被吞的 具体实现代码: ```python import os # 15 上传用户头像 http://127.0.0.1:8888/static/picture/xXxX.jpg def UserPicture(request): if request.method == 'POST': fileName = request.FILES.get('file').name # 当前脚本的绝对路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) upload_path = BASE_DIR + '/static/picture/'+fileName fileData = request.FILES.get('file').read() with open(upload_path, "wb+") as f: f.write(fileData) # do something else with the image if needed response = { 'img': "http://127.0.0.1:8888/static/picture/"+fileName } json_str = json.dumps(response, default=lambda o: o.__json__() if isinstance(o, (str)) else None, ensure_ascii=False) return HttpResponse(json_str,content_type="application/json") ```