This commit is contained in:
Tim 2023-07-01 16:39:31 +08:00
commit 59f6d16538
432 changed files with 45962 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
/server/myapp/migrations
/server/myapp/views/__pycache__/
/server/.idea
/web/.idea
/web/dist
/web/node_modules
/server/.idea/
/.idea/
__pycache__
.idea
server/.idea
.DS_Store
server/.DS_Store
web/.DS_Store

99
Readme.md Normal file
View File

@ -0,0 +1,99 @@
### 功能介绍
平台采用B/S结构后端采用主流的Python语言进行开发前端采用主流的Vue.js进行开发。
整个平台包括前台和后台两个部分。
- 前台功能包括:首页、家教详情页、用户中心、家教入驻模块。
- 后台功能包括:总览、家教管理、分类管理、标签管理、评论管理、用户管理、运营管理、日志管理、系统信息模块。
### 源码下载
https://github.com/geeeeeeeek/python_jiajiao
### 效果演示
前台地址:
后台地址:
后台管理帐号:
用户名admin123
密码admin123
### 代码结构
- server目录是后端代码
- web目录是前端代码
### 运行步骤
#### 后端运行步骤
(1) 安装python 3.8
(2) 安装依赖。进入server目录下执行 pip install -r requirements.txt
(3) 安装mysql 5.7数据库并创建数据库创建SQL如下
```
CREATE DATABASE IF NOT EXISTS python_jiajiao DEFAULT CHARSET utf8 COLLATE utf8_general_ci
```
(4) 恢复shop.sql数据。在mysql下依次执行如下命令
```
mysql> use xxx;
mysql> source D:/xxx/xxx/xxx.sql;
```
(5) 启动django服务。在server目录下执行
```
python manage.py runserver
```
#### 前端运行步骤
(1) 安装node 16.14
(2) 进入web目录下安装依赖执行:
```
npm install
```
(3) 运行项目
```
npm run serve
```
### 界面预览
首页
![]()
后台页面
![]()
### 待完善功能
- 邮箱推送功能
- 手机号绑定功能
- 粉丝关注功能
- 支付功能
### 付费咨询
微信lengqin1024
### 获取完整代码
微信lengqin1024

22
server/manage.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

0
server/myapp/__init__.py Normal file
View File

10
server/myapp/admin.py Normal file
View File

@ -0,0 +1,10 @@
from django.contrib import admin
# Register your models here.
from myapp.models import Classification, Thing, Tag, User, Comment
admin.site.register(Classification)
admin.site.register(Tag)
admin.site.register(Thing)
admin.site.register(User)
admin.site.register(Comment)

6
server/myapp/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class MyappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'

View File

@ -0,0 +1,5 @@
from rest_framework.throttling import AnonRateThrottle
class MyRateThrottle(AnonRateThrottle):
THROTTLE_RATES = {"anon": "5/min"}

View File

View File

@ -0,0 +1,46 @@
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from myapp.models import User
# 后台接口认证
class AdminTokenAuthtication(BaseAuthentication):
def authenticate(self, request):
adminToken = request.META.get("HTTP_ADMINTOKEN")
print("检查adminToken==>" + adminToken)
users = User.objects.filter(admin_token=adminToken)
"""
判定条件
1. 传了adminToken
2. 查到了该帐号
3. 该帐号是管理员或演示帐号
"""
if not adminToken or len(users) == 0 or users[0].role == '2':
raise exceptions.AuthenticationFailed("AUTH_FAIL_END")
else:
print('adminToken验证通过')
# 前台接口认证
class TokenAuthtication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get("HTTP_TOKEN", "")
if token is not None:
print("检查token==>" + token)
users = User.objects.filter(token=token)
# print(users)
"""
判定条件
1. 传了token
2. 查到了该帐号
3. 该帐号是普通用户
"""
if not token or len(users) == 0 or (users[0].role in ['1', '3']):
raise exceptions.AuthenticationFailed("AUTH_FAIL_FRONT")
else:
print('token验证通过')
else:
print("检查token==>token 为空")
raise exceptions.AuthenticationFailed("AUTH_FAIL_FRONT")

13
server/myapp/handler.py Normal file
View File

@ -0,0 +1,13 @@
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=0, msg='', data=None, status=200, headers=None, content_type=None, **kwargs):
dic = {'code': code, 'msg': msg}
if data is not None:
dic['data'] = data
dic.update(kwargs) # 这里使用update
super().__init__(data=dic, status=status,
template_name=None, headers=headers,
exception=False, content_type=content_type)

View File

@ -0,0 +1,54 @@
# -*- coding:utf-8 -*-
import time
import json
from django.utils.deprecation import MiddlewareMixin
from myapp import utils
from myapp.serializers import OpLogSerializer
class OpLogs(MiddlewareMixin):
def __init__(self, *args):
super(OpLogs, self).__init__(*args)
self.start_time = None # 开始时间
self.end_time = None # 响应时间
self.data = {} # dict数据
def process_request(self, request):
self.start_time = time.time() # 开始时间
re_ip = utils.get_ip(request)
re_method = request.method
re_content = request.GET if re_method == 'GET' else request.POST
if re_content:
re_content = json.dumps(re_content)
else:
re_content = None
self.data.update(
{
're_url': request.path,
're_method': re_method,
're_ip': re_ip,
# 're_content': re_content,
}
)
# print(self.data)
def process_response(self, request, response):
# 耗时毫秒/ms
self.end_time = time.time() # 响应时间
access_time = self.end_time - self.start_time
self.data['access_time'] = round(access_time * 1000)
# 入库
# serializer = OpLogSerializer(data=self.data)
# if serializer.is_valid():
# serializer.save()
return response

View File

222
server/myapp/models.py Normal file
View File

@ -0,0 +1,222 @@
from django.db import models
class User(models.Model):
GENDER_CHOICES = (
('M', ''),
('F', ''),
)
ROLE_CHOICES = (
('0', '管理员'),
('1', '普通用户'),
)
STATUS_CHOICES = (
('0', '正常'),
('1', '封号'),
)
id = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=50, null=True)
password = models.CharField(max_length=50, null=True)
role = models.CharField(max_length=2, blank=True, null=True)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='0')
nickname = models.CharField(blank=True, null=True, max_length=20)
avatar = models.FileField(upload_to='avatar/', null=True)
mobile = models.CharField(max_length=13, blank=True, null=True)
email = models.CharField(max_length=50, blank=True, null=True)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True, null=True)
description = models.TextField(max_length=200, null=True)
create_time = models.DateTimeField(auto_now_add=True, null=True)
score = models.IntegerField(default=0, blank=True, null=True)
push_email = models.CharField(max_length=40, blank=True, null=True)
push_switch = models.BooleanField(blank=True, null=True, default=False)
admin_token = models.CharField(max_length=32, blank=True, null=True)
token = models.CharField(max_length=32, blank=True, null=True)
class Meta:
db_table = "b_user"
class Tag(models.Model):
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=100, blank=True, null=True)
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_tag"
class Classification(models.Model):
list_display = ("title", "id")
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=100, blank=True, null=True)
create_time = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.title
class Meta:
db_table = "b_classification"
class Thing(models.Model):
STATUS_CHOICES = (
('0', '上架'),
('1', '下架'),
)
id = models.BigAutoField(primary_key=True)
classification = models.ForeignKey(Classification, on_delete=models.CASCADE, blank=True, null=True,
related_name='classification_thing')
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name='user_thing')
tag = models.ManyToManyField(Tag, blank=True)
title = models.CharField(max_length=100, blank=True, null=True)
cover = models.ImageField(upload_to='cover/', null=True)
description = models.TextField(max_length=1000, blank=True, null=True)
price = models.CharField(max_length=50, blank=True, null=True)
mobile = models.CharField(max_length=50, blank=True, null=True)
age = models.CharField(max_length=10, blank=True, null=True)
sex = models.CharField(max_length=2, blank=True, null=True)
location = models.CharField(max_length=50, blank=True, null=True)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='0')
create_time = models.DateTimeField(auto_now_add=True, null=True)
pv = models.IntegerField(default=0)
recommend_count = models.IntegerField(default=0)
wish = models.ManyToManyField(User, blank=True, related_name="wish_things")
wish_count = models.IntegerField(default=0)
collect = models.ManyToManyField(User, blank=True, related_name="collect_things")
collect_count = models.IntegerField(default=0)
class Meta:
db_table = "b_thing"
class Comment(models.Model):
id = models.BigAutoField(primary_key=True)
content = models.CharField(max_length=200, blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='user_comment')
thing = models.ForeignKey(Thing, on_delete=models.CASCADE, null=True, related_name='thing_comment')
comment_time = models.DateTimeField(auto_now_add=True, null=True)
like_count = models.IntegerField(default=0)
class Meta:
db_table = "b_comment"
class Record(models.Model):
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='user_record')
thing = models.ForeignKey(Thing, on_delete=models.CASCADE, null=True, related_name='thing_record')
title = models.CharField(max_length=100, blank=True, null=True)
classification = models.ForeignKey(Classification, on_delete=models.CASCADE, null=True,
related_name='classification')
record_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_record"
class LoginLog(models.Model):
id = models.BigAutoField(primary_key=True)
username = models.CharField(max_length=50, blank=True, null=True)
ip = models.CharField(max_length=100, blank=True, null=True)
ua = models.CharField(max_length=200, blank=True, null=True)
log_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_login_log"
class OpLog(models.Model):
id = models.BigAutoField(primary_key=True)
re_ip = models.CharField(max_length=100, blank=True, null=True)
re_time = models.DateTimeField(auto_now_add=True, null=True)
re_url = models.CharField(max_length=200, blank=True, null=True)
re_method = models.CharField(max_length=10, blank=True, null=True)
re_content = models.CharField(max_length=200, blank=True, null=True)
access_time = models.CharField(max_length=10, blank=True, null=True)
class Meta:
db_table = "b_op_log"
class ErrorLog(models.Model):
id = models.BigAutoField(primary_key=True)
ip = models.CharField(max_length=100, blank=True, null=True)
url = models.CharField(max_length=200, blank=True, null=True)
method = models.CharField(max_length=10, blank=True, null=True)
content = models.CharField(max_length=200, blank=True, null=True)
log_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_error_log"
class Order(models.Model):
id = models.BigAutoField(primary_key=True)
order_number = models.CharField(max_length=13, blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='user_order')
thing = models.ForeignKey(Thing, on_delete=models.CASCADE, null=True, related_name='thing_order')
count = models.IntegerField(default=0)
status = models.CharField(max_length=2, blank=True, null=True) # 1未支付 2已支付 7订单取消
order_time = models.DateTimeField(auto_now_add=True, null=True)
pay_time = models.DateTimeField(null=True)
receiver_name = models.CharField(max_length=20, blank=True, null=True)
receiver_address = models.CharField(max_length=50, blank=True, null=True)
receiver_phone = models.CharField(max_length=20, blank=True, null=True)
remark = models.CharField(max_length=30, blank=True, null=True)
class Meta:
db_table = "b_order"
class OrderLog(models.Model):
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='user_order_log')
thing = models.ForeignKey(Thing, on_delete=models.CASCADE, null=True, related_name='thing_order_log')
action = models.CharField(max_length=2, blank=True, null=True)
log_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_order_log"
class Banner(models.Model):
id = models.BigAutoField(primary_key=True)
image = models.ImageField(upload_to='banner/', null=True)
thing = models.ForeignKey(Thing, on_delete=models.CASCADE, null=True, related_name='thing_banner')
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_banner"
class Ad(models.Model):
id = models.BigAutoField(primary_key=True)
image = models.ImageField(upload_to='ad/', null=True)
link = models.CharField(max_length=500, blank=True, null=True)
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_ad"
class Notice(models.Model):
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=100, blank=True, null=True)
content = models.CharField(max_length=1000, blank=True, null=True)
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_notice"
class Address(models.Model):
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='user_address')
name = models.CharField(max_length=100, blank=True, null=True)
mobile = models.CharField(max_length=30, blank=True, null=True)
desc = models.CharField(max_length=300, blank=True, null=True)
default = models.BooleanField(blank=True, null=True, default=False) # 是否默认地址
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
db_table = "b_address"

View File

View File

@ -0,0 +1,12 @@
from myapp.models import User
def isDemoAdminUser(request):
adminToken = request.META.get("HTTP_ADMINTOKEN")
users = User.objects.filter(admin_token=adminToken)
if len(users) > 0:
user = users[0]
if user.role == '3': # 角色3表示演示帐号
print('演示帐号===>')
return True
return False

157
server/myapp/serializers.py Normal file
View File

@ -0,0 +1,157 @@
from rest_framework import serializers
from myapp.models import Thing, Classification, Tag, User, Comment, Record, LoginLog, Order, OrderLog, OpLog, Banner, \
Ad, Notice, ErrorLog, Address
class ThingSerializer(serializers.ModelSerializer):
# 额外字段
classification_title = serializers.ReadOnlyField(source='classification.title')
class Meta:
model = Thing
fields = '__all__'
class DetailThingSerializer(serializers.ModelSerializer):
# 额外字段
classification_title = serializers.ReadOnlyField(source='classification.title')
class Meta:
model = Thing
# 排除多对多字段
exclude = ('wish', 'collect',)
class UpdateThingSerializer(serializers.ModelSerializer):
# 额外字段
classification_title = serializers.ReadOnlyField(source='classification.title')
class Meta:
model = Thing
# 排除多对多字段
exclude = ('wish', 'collect',)
class ListThingSerializer(serializers.ModelSerializer):
# 额外字段
classification_title = serializers.ReadOnlyField(source='classification.title')
class Meta:
model = Thing
# 排除字段
exclude = ('wish', 'collect',)
class ClassificationSerializer(serializers.ModelSerializer):
class Meta:
model = Classification
fields = '__all__'
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = '__all__'
class UserSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = User
fields = '__all__'
# exclude = ('password',)
class CommentSerializer(serializers.ModelSerializer):
comment_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
# 额外字段
title = serializers.ReadOnlyField(source='thing.title')
username = serializers.ReadOnlyField(source='user.username')
class Meta:
model = Comment
fields = ['id', 'content', 'comment_time', 'like_count', 'thing', 'user', 'title', 'username']
class RecordSerializer(serializers.ModelSerializer):
class Meta:
model = Record
fields = '__all__'
class LoginLogSerializer(serializers.ModelSerializer):
log_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = LoginLog
fields = '__all__'
class OpLogSerializer(serializers.ModelSerializer):
re_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = OpLog
fields = '__all__'
class ErrorLogSerializer(serializers.ModelSerializer):
log_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = ErrorLog
fields = '__all__'
class OrderSerializer(serializers.ModelSerializer):
order_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
expect_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
return_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
# extra
username = serializers.ReadOnlyField(source='user.username')
title = serializers.ReadOnlyField(source='thing.title')
price = serializers.ReadOnlyField(source='thing.price')
cover = serializers.FileField(source='thing.cover', required=False)
class Meta:
model = Order
fields = '__all__'
class OrderLogSerializer(serializers.ModelSerializer):
class Meta:
model = OrderLog
fields = '__all__'
class BannerSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
# extra
title = serializers.ReadOnlyField(source='thing.title')
class Meta:
model = Banner
fields = '__all__'
class AdSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = Ad
fields = '__all__'
class NoticeSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = Notice
fields = '__all__'
class AddressSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
class Meta:
model = Address
fields = '__all__'

3
server/myapp/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

101
server/myapp/urls.py Normal file
View File

@ -0,0 +1,101 @@
from django.urls import path
from myapp import views
app_name = 'myapp'
urlpatterns = [
# 后台管理api
path('admin/overview/count', views.admin.overview.count),
path('admin/overview/sysInfo', views.admin.overview.sysInfo),
path('admin/thing/list', views.admin.thing.list_api),
path('admin/thing/detail', views.admin.thing.detail),
path('admin/thing/create', views.admin.thing.create),
path('admin/thing/update', views.admin.thing.update),
path('admin/thing/delete', views.admin.thing.delete),
path('admin/comment/list', views.admin.comment.list_api),
path('admin/comment/create', views.admin.comment.create),
path('admin/comment/update', views.admin.comment.update),
path('admin/comment/delete', views.admin.comment.delete),
path('admin/classification/list', views.admin.classification.list_api),
path('admin/classification/create', views.admin.classification.create),
path('admin/classification/update', views.admin.classification.update),
path('admin/classification/delete', views.admin.classification.delete),
path('admin/tag/list', views.admin.tag.list_api),
path('admin/tag/create', views.admin.tag.create),
path('admin/tag/update', views.admin.tag.update),
path('admin/tag/delete', views.admin.tag.delete),
path('admin/record/list', views.admin.record.list_api),
path('admin/record/create', views.admin.record.create),
path('admin/record/update', views.admin.record.update),
path('admin/record/delete', views.admin.record.delete),
path('admin/banner/list', views.admin.banner.list_api),
path('admin/banner/create', views.admin.banner.create),
path('admin/banner/update', views.admin.banner.update),
path('admin/banner/delete', views.admin.banner.delete),
path('admin/ad/list', views.admin.ad.list_api),
path('admin/ad/create', views.admin.ad.create),
path('admin/ad/update', views.admin.ad.update),
path('admin/ad/delete', views.admin.ad.delete),
path('admin/notice/list', views.admin.notice.list_api),
path('admin/notice/create', views.admin.notice.create),
path('admin/notice/update', views.admin.notice.update),
path('admin/notice/delete', views.admin.notice.delete),
path('admin/order/list', views.admin.order.list_api),
path('admin/order/create', views.admin.order.create),
path('admin/order/update', views.admin.order.update),
path('admin/order/cancel_order', views.admin.order.cancel_order),
path('admin/order/delay', views.admin.order.delay),
path('admin/order/delete', views.admin.order.delete),
path('admin/loginLog/list', views.admin.loginLog.list_api),
path('admin/loginLog/create', views.admin.loginLog.create),
path('admin/loginLog/update', views.admin.loginLog.update),
path('admin/loginLog/delete', views.admin.loginLog.delete),
path('admin/opLog/list', views.admin.opLog.list_api),
path('admin/errorLog/list', views.admin.errorLog.list_api),
path('admin/user/list', views.admin.user.list_api),
path('admin/user/create', views.admin.user.create),
path('admin/user/update', views.admin.user.update),
path('admin/user/updatePwd', views.admin.user.updatePwd),
path('admin/user/delete', views.admin.user.delete),
path('admin/user/info', views.admin.user.info),
path('admin/adminLogin', views.admin.user.admin_login),
# 前台管理api
path('index/classification/list', views.index.classification.list_api),
path('index/tag/list', views.index.tag.list_api),
path('index/user/login', views.index.user.login),
path('index/user/register', views.index.user.register),
path('index/user/info', views.index.user.info),
path('index/user/update', views.index.user.update),
path('index/user/updatePwd', views.index.user.updatePwd),
path('index/notice/list_api', views.index.notice.list_api),
path('index/thing/list', views.index.thing.list_api),
path('index/thing/detail', views.index.thing.detail),
path('index/thing/increaseWishCount', views.index.thing.increaseWishCount),
path('index/thing/addWishUser', views.index.thing.addWishUser),
path('index/thing/removeWishUser', views.index.thing.removeWishUser),
path('index/thing/getWishThingList', views.index.thing.getWishThingList),
path('index/thing/addCollectUser', views.index.thing.addCollectUser),
path('index/thing/removeCollectUser', views.index.thing.removeCollectUser),
path('index/thing/getCollectThingList', views.index.thing.getCollectThingList),
path('index/thing/increaseRecommendCount', views.index.thing.increaseRecommendCount),
path('index/thing/listUserThing', views.index.thing.list_user_thing_api),
path('index/thing/create', views.index.thing.create),
path('index/thing/update', views.index.thing.update),
path('index/comment/list', views.index.comment.list_api),
path('index/comment/listMyComments', views.index.comment.list_my_comment),
path('index/comment/create', views.index.comment.create),
path('index/comment/delete', views.index.comment.delete),
path('index/comment/like', views.index.comment.like),
path('index/order/list', views.index.order.list_api),
path('index/order/create', views.index.order.create),
path('index/order/cancel_order', views.index.order.cancel_order),
path('index/address/list', views.index.address.list_api),
path('index/address/create', views.index.address.create),
path('index/address/update', views.index.address.update),
path('index/address/delete', views.index.address.delete),
]

87
server/myapp/utils.py Normal file
View File

@ -0,0 +1,87 @@
import datetime
import hashlib
import time
from rest_framework.views import exception_handler
from myapp.serializers import ErrorLogSerializer
def get_timestamp():
return int(round(time.time() * 1000))
def md5value(key):
input_name = hashlib.md5()
input_name.update(key.encode("utf-8"))
md5str = (input_name.hexdigest()).lower()
print('计算md5:', md5str)
return md5str
def dict_fetchall(cursor): # cursor是执行sql_str后的记录作入参
columns = [col[0] for col in cursor.description] # 得到域的名字col[0]组成List
return [
dict(zip(columns, row)) for row in cursor.fetchall()
]
def get_ip(request):
"""
获取请求者的IP信息
"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def get_ua(request):
"""
获取请求者的IP信息
"""
ua = request.META.get('HTTP_USER_AGENT')
return ua[0:200]
def getWeekDays():
"""
获取近一周的日期
"""
week_days = []
now = datetime.datetime.now()
for i in range(7):
day = now - datetime.timedelta(days=i)
week_days.append(day.strftime('%Y-%m-%d %H:%M:%S.%f')[:10])
week_days.reverse() # 逆序
return week_days
def get_monday():
"""
获取本周周一日期
"""
now = datetime.datetime.now()
monday = now - datetime.timedelta(now.weekday())
return monday.strftime('%Y-%m-%d %H:%M:%S.%f')[:10]
def log_error(request, content):
"""
记录错误日志
"""
ip = get_ip(request)
method = request.method
url = request.path
data = {
'ip': ip,
'method': method,
'url': url,
'content': content
}
# 入库
serializer = ErrorLogSerializer(data=data)
if serializer.is_valid():
serializer.save()

View File

@ -0,0 +1,2 @@
from myapp.views.admin import *
from myapp.views.index import *

View File

@ -0,0 +1,14 @@
from myapp.views.admin.thing import *
from myapp.views.admin.classification import *
from myapp.views.admin.tag import *
from myapp.views.admin.user import *
from myapp.views.admin.comment import *
from myapp.views.admin.record import *
from myapp.views.admin.overview import *
from myapp.views.admin.loginLog import *
from myapp.views.admin.order import *
from myapp.views.admin.opLog import *
from myapp.views.admin.errorLog import *
from myapp.views.admin.banner import *
from myapp.views.admin.ad import *
from myapp.views.admin.notice import *

View File

@ -0,0 +1,68 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Ad
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import AdSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
ads = Ad.objects.all().order_by('-create_time')
serializer = AdSerializer(ads, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
serializer = AdSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
ad = Ad.objects.get(pk=pk)
except Ad.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = AdSerializer(ad, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Ad.objects.filter(id__in=ids_arr).delete()
except Ad.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,68 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Banner
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import BannerSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
banners = Banner.objects.all().order_by('-create_time')
serializer = BannerSerializer(banners, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
serializer = BannerSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
banner = Banner.objects.get(pk=pk)
except Banner.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = BannerSerializer(banner, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Banner.objects.filter(id__in=ids_arr).delete()
except Banner.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,74 @@
# Create your views here.
from django.db import connection
from django.db.models import Q
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Classification
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import ClassificationSerializer
from myapp.utils import dict_fetchall
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
classifications = Classification.objects.all().order_by('-create_time')
serializer = ClassificationSerializer(classifications, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
classification = Classification.objects.filter(title=request.data['title'])
if len(classification) > 0:
return APIResponse(code=1, msg='该名称已存在')
serializer = ClassificationSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
print(pk)
classification = Classification.objects.get(pk=pk)
except Classification.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = ClassificationSerializer(classification, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
# 删除自身和自身的子孩子
Classification.objects.filter(Q(id__in=ids_arr)).delete()
except Classification.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,69 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Comment
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import CommentSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
comments = Comment.objects.select_related("thing").all().order_by('-comment_time')
# print(comments)
serializer = CommentSerializer(comments, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
serializer = CommentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
comments = Comment.objects.get(pk=pk)
except Comment.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = CommentSerializer(comments, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Comment.objects.filter(id__in=ids_arr).delete()
except Comment.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,14 @@
# Create your views here.
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import ErrorLog
from myapp.serializers import ErrorLogSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
errorLogs = ErrorLog.objects.all().order_by('-log_time')
serializer = ErrorLogSerializer(errorLogs, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)

View File

@ -0,0 +1,60 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import LoginLog
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import LoginLogSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
loginLogs = LoginLog.objects.all().order_by('-log_time')
serializer = LoginLogSerializer(loginLogs, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
def create(request):
serializer = LoginLogSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
try:
pk = request.GET.get('id', -1)
loginLogs = LoginLog.objects.get(pk=pk)
except LoginLog.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = LoginLogSerializer(loginLogs, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
LoginLog.objects.filter(id__in=ids_arr).delete()
except LoginLog.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,68 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Notice
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import NoticeSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
notices = Notice.objects.all().order_by('-create_time')
serializer = NoticeSerializer(notices, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
serializer = NoticeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
notice = Notice.objects.get(pk=pk)
except Notice.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = NoticeSerializer(notice, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Notice.objects.filter(id__in=ids_arr).delete()
except Notice.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,14 @@
# Create your views here.
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import OpLog
from myapp.serializers import OpLogSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
opLogs = OpLog.objects.all().order_by('-re_time')[:100]
serializer = OpLogSerializer(opLogs, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)

View File

@ -0,0 +1,147 @@
# Create your views here.
import datetime
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Order, Thing
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import OrderSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
orders = Order.objects.all().order_by('-order_time')
serializer = OrderSerializer(orders, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
"""
创建订单
"""
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
data = request.data.copy()
if data['user'] is None or data['thing'] is None or data['count'] is None:
return APIResponse(code=1, msg='参数错误')
thing = Thing.objects.get(pk=data['thing'])
count = data['count']
if thing.repertory < int(count):
return APIResponse(code=1, msg='库存不足')
create_time = datetime.datetime.now()
data['create_time'] = create_time
data['order_number'] = str(utils.get_timestamp())
data['status'] = '1'
serializer = OrderSerializer(data=data)
if serializer.is_valid():
serializer.save()
# 减库存(支付后)
# thing.repertory = thing.repertory - int(count)
# thing.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
order = Order.objects.get(pk=pk)
except Order.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = OrderSerializer(order, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def cancel_order(request):
"""
取消
"""
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
order = Order.objects.get(pk=pk)
except Order.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
data = {
'status': 7
}
serializer = OrderSerializer(order, data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='取消成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delay(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
order = Order.objects.get(pk=pk)
except Order.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
if order.delayed:
return APIResponse(code=1, msg='已超最大延期次数')
else:
data = {
"delayed": True,
"expect_time": order.expect_time + datetime.timedelta(days=30)
}
serializer = OrderSerializer(order, data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='延期成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='延期失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Order.objects.filter(id__in=ids_arr).delete()
except Order.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,98 @@
# Create your views here.
import datetime
import locale
import platform
import random
import time
from multiprocessing import cpu_count
import psutil
from django.db import connection
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.handler import APIResponse
from myapp.models import Thing, Order
from myapp.utils import dict_fetchall
from myapp.auth.authentication import AdminTokenAuthtication
@api_view(['GET'])
@authentication_classes([AdminTokenAuthtication])
def count(request):
if request.method == 'GET':
now = datetime.datetime.now()
# 统计排名(sql语句)
sql_str = "select title, pv as count from b_thing order by count desc limit 10; "
with connection.cursor() as cursor:
cursor.execute(sql_str)
order_rank_data = dict_fetchall(cursor)
# 统计分类比例(sql语句)
sql_str = "select B.title, count(B.title) as count from b_thing A join B_classification B on " \
"A.classification_id = B.id group by B.title order by count desc limit 5; "
with connection.cursor() as cursor:
cursor.execute(sql_str)
classification_rank_data = dict_fetchall(cursor)
# 统计最近一周访问量(sql语句)
visit_data = []
week_days = utils.getWeekDays()
for day in week_days:
sql_str = "select re_ip, count(re_ip) as count from b_op_log where re_time like '" + day + "%' group by re_ip"
with connection.cursor() as cursor:
cursor.execute(sql_str)
ip_data = dict_fetchall(cursor)
uv = len(ip_data)
pv = 0
for item in ip_data:
pv = pv + item['count']
visit_data.append({
"day": day,
"uv": uv + random.randint(1, 20),
"pv": pv + random.randint(20, 100)
})
data = {
'order_rank_data': order_rank_data,
'classification_rank_data': classification_rank_data,
'visit_data': visit_data
}
return APIResponse(code=0, msg='查询成功', data=data)
@api_view(['GET'])
@authentication_classes([AdminTokenAuthtication])
def sysInfo(request):
if request.method == 'GET':
pyVersion = platform.python_version()
osBuild = platform.architecture()
node = platform.node()
pf = platform.platform()
processor = platform.processor()
pyComp = platform.python_compiler()
osName = platform.system()
memory = psutil.virtual_memory()
data = {
'sysName': '家教管理系统',
'versionName': '1.1.0',
'osName': osName,
'pyVersion': pyVersion,
'osBuild': osBuild,
'node': node,
'pf': pf,
'processor': processor,
'cpuCount': cpu_count(),
'pyComp': pyComp,
'cpuLoad': round((psutil.cpu_percent(1)), 2),
'memory': round((float(memory.total) / 1024 / 1024 / 1024), 2),
'usedMemory': round((float(memory.used) / 1024 / 1024 / 1024), 2),
'percentMemory': round((float(memory.used) / float(memory.total) * 100), 2),
'sysLan': locale.getdefaultlocale(),
'sysZone': time.strftime('%Z', time.localtime())
}
return APIResponse(code=0, msg='查询成功', data=data)

View File

@ -0,0 +1,53 @@
# Create your views here.
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import Record
from myapp.serializers import RecordSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
records = Record.objects.all()
serializer = RecordSerializer(records, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
def create(request):
serializer = RecordSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
def update(request):
try:
pk = request.GET.get('id', -1)
records = Record.objects.get(pk=pk)
except Record.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = RecordSerializer(records, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
def delete(request):
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Record.objects.filter(id__in=ids_arr).delete()
except Record.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,75 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Tag
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import TagSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
tags = Tag.objects.all().order_by('-create_time')
serializer = TagSerializer(tags, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
tags = Tag.objects.filter(title=request.data['title'])
if len(tags) > 0:
return APIResponse(code=1, msg='该名称已存在')
serializer = TagSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
tags = Tag.objects.get(pk=pk)
except Tag.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = TagSerializer(tags, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Tag.objects.filter(id__in=ids_arr).delete()
except Tag.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,104 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Classification, Thing, Tag
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import ThingSerializer, UpdateThingSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
keyword = request.GET.get("keyword", None)
c = request.GET.get("c", None)
tag = request.GET.get("tag", None)
if keyword:
things = Thing.objects.filter(title__contains=keyword).order_by('create_time')
elif c:
classification = Classification.objects.get(pk=c)
things = classification.classification_thing.all()
elif tag:
tag = Tag.objects.get(id=tag)
print(tag)
things = tag.thing_set.all()
else:
things = Thing.objects.all().order_by('create_time')
serializer = ThingSerializer(things, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['GET'])
def detail(request):
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
except Thing.DoesNotExist:
utils.log_error(request, '对象不存在')
return APIResponse(code=1, msg='对象不存在')
if request.method == 'GET':
serializer = ThingSerializer(thing)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
serializer = ThingSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
except Thing.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = UpdateThingSerializer(thing, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
print(serializer.errors)
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Thing.objects.filter(id__in=ids_arr).delete()
except Thing.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,176 @@
# Create your views here.
import datetime
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import User
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import UserSerializer, LoginLogSerializer
from myapp.utils import md5value
def make_login_log(request):
try:
username = request.data['username']
data = {
"username": username,
"ip": utils.get_ip(request),
"ua": utils.get_ua(request)
}
serializer = LoginLogSerializer(data=data)
if serializer.is_valid():
serializer.save()
else:
print(serializer.errors)
except Exception as e:
print(e)
@api_view(['POST'])
def admin_login(request):
username = request.data['username']
password = utils.md5value(request.data['password'])
users = User.objects.filter(username=username, password=password, role__in=['1', '3'])
if len(users) > 0:
user = users[0]
data = {
'username': username,
'password': password,
'admin_token': md5value(username) # 生成令牌
}
serializer = UserSerializer(user, data=data)
if serializer.is_valid():
serializer.save()
make_login_log(request)
return APIResponse(code=0, msg='登录成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='用户名或密码错误')
@api_view(['GET'])
def info(request):
if request.method == 'GET':
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
serializer = UserSerializer(user)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
keyword = request.GET.get("keyword", '')
users = User.objects.filter(username__contains=keyword).order_by('-create_time')
serializer = UserSerializer(users, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def create(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
print(request.data)
if not request.data.get('username', None) or not request.data.get('password', None):
return APIResponse(code=1, msg='用户名或密码不能为空')
users = User.objects.filter(username=request.data['username'])
if len(users) > 0:
return APIResponse(code=1, msg='该用户名已存在')
data = request.data.copy()
data.update({'password': utils.md5value(request.data['password'])})
serializer = UserSerializer(data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def update(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
except User.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
data = request.data.copy()
if 'username' in data.keys():
del data['username']
if 'password' in data.keys():
del data['password']
serializer = UserSerializer(user, data=data)
print(serializer.is_valid())
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def updatePwd(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
except User.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
password = request.data.get('password', None)
newPassword1 = request.data.get('newPassword1', None)
newPassword2 = request.data.get('newPassword2', None)
if not password or not newPassword1 or not newPassword2:
return APIResponse(code=1, msg='不能为空')
if user.password != utils.md5value(password):
return APIResponse(code=1, msg='原密码不正确')
if newPassword1 != newPassword2:
return APIResponse(code=1, msg='两次密码不一致')
data = request.data.copy()
data.update({'password': utils.md5value(newPassword1)})
serializer = UserSerializer(user, data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([AdminTokenAuthtication])
def delete(request):
if isDemoAdminUser(request):
return APIResponse(code=1, msg='演示帐号无法操作')
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
User.objects.filter(id__in=ids_arr).delete()
except User.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,8 @@
from myapp.views.index.classification import *
from myapp.views.index.tag import *
from myapp.views.index.user import *
from myapp.views.index.thing import *
from myapp.views.index.comment import *
from myapp.views.index.order import *
from myapp.views.index.notice import *
from myapp.views.index.address import *

View File

@ -0,0 +1,87 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import TokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Address
from myapp.serializers import AddressSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
userId = request.GET.get('userId', -1)
if userId != -1:
addresses = Address.objects.filter(user=userId).order_by('-create_time')
serializer = AddressSerializer(addresses, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
return APIResponse(code=1, msg='userId不能为空')
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def create(request):
address_content = request.POST.get('desc', None)
user = request.POST.get('user', None)
default = request.POST.get('default', False)
if address_content is None or user is None:
return APIResponse(code=1, msg='不能为空')
if default:
# 其他置为false
Address.objects.filter(user=user).update(default=False)
serializer = AddressSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def update(request):
try:
pk = request.GET.get('id', -1)
addresses = Address.objects.get(pk=pk)
except Address.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
user = request.data['user']
default = request.data['default']
if default:
# 其他置为false
Address.objects.filter(user=user).update(default=False)
serializer = AddressSerializer(addresses, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def delete(request):
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Address.objects.filter(id__in=ids_arr).delete()
except Address.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')

View File

@ -0,0 +1,21 @@
# Create your views here.
from django.db import connection
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import Classification
from myapp.serializers import ClassificationSerializer
from myapp.utils import dict_fetchall
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
classifications = Classification.objects.all().order_by('-create_time')
serializer = ClassificationSerializer(classifications, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)

View File

@ -0,0 +1,87 @@
# Create your views here.
from rest_framework.decorators import api_view, authentication_classes, throttle_classes
from myapp.auth.MyRateThrottle import MyRateThrottle
from myapp.auth.authentication import AdminTokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Comment
from myapp.permission.permission import isDemoAdminUser
from myapp.serializers import CommentSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
thingId = request.GET.get("thingId", None)
order = request.GET.get("order", 'recent')
if thingId:
if order == 'recent':
orderBy = '-comment_time'
else:
orderBy = '-like_count'
comments = Comment.objects.select_related("thing").filter(thing=thingId).order_by(orderBy)
# print(comments)
serializer = CommentSerializer(comments, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
return APIResponse(code=1, msg='thingId不能为空')
@api_view(['GET'])
def list_my_comment(request):
if request.method == 'GET':
userId = request.GET.get("userId", None)
order = request.GET.get("order", 'recent')
if userId:
if order == 'recent':
orderBy = '-comment_time'
else:
orderBy = '-like_count'
comments = Comment.objects.select_related("thing").filter(user=userId).order_by(orderBy)
# print(comments)
serializer = CommentSerializer(comments, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
return APIResponse(code=1, msg='userId不能为空')
@api_view(['POST'])
@throttle_classes([MyRateThrottle])
def create(request):
serializer = CommentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
def delete(request):
try:
ids = request.GET.get('ids')
ids_arr = ids.split(',')
Comment.objects.filter(id__in=ids_arr).delete()
except Comment.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='删除成功')
@api_view(['POST'])
def like(request):
try:
commentId = request.GET.get('commentId')
comment = Comment.objects.get(pk=commentId)
comment.like_count += 1
comment.save()
except Comment.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
return APIResponse(code=0, msg='推荐成功')

View File

@ -0,0 +1,15 @@
# Create your views here.
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import Notice
from myapp.serializers import NoticeSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
notices = Notice.objects.all().order_by('-create_time')
serializer = NoticeSerializer(notices, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)

View File

@ -0,0 +1,85 @@
# Create your views here.
import datetime
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import TokenAuthtication
from myapp.handler import APIResponse
from myapp.models import Order, Thing
from myapp.serializers import OrderSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
userId = request.GET.get('userId', -1)
orderStatus = request.GET.get('orderStatus', '')
orders = Order.objects.all().filter(user=userId).filter(status__contains=orderStatus).order_by('-order_time')
serializer = OrderSerializer(orders, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def create(request):
data = request.data.copy()
if data['user'] is None or data['thing'] is None or data['count'] is None:
return APIResponse(code=1, msg='参数错误')
thing = Thing.objects.get(pk=data['thing'])
count = data['count']
if thing.repertory < int(count):
return APIResponse(code=1, msg='库存不足')
create_time = datetime.datetime.now()
data['create_time'] = create_time
data['order_number'] = str(utils.get_timestamp())
data['status'] = '1'
serializer = OrderSerializer(data=data)
if serializer.is_valid():
serializer.save()
# 减库存(支付后)
# thing.repertory = thing.repertory - int(count)
# thing.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def cancel_order(request):
"""
cancal
"""
try:
pk = request.GET.get('id', -1)
order = Order.objects.get(pk=pk)
except Order.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
data = {
'status': 7
}
serializer = OrderSerializer(order, data=data)
if serializer.is_valid():
serializer.save()
# 加库存
# thingId = request.data['thing']
# thing = Thing.objects.get(pk=thingId)
# thing.repertory = thing.repertory + 1
# thing.save()
# 加积分
# order.user.score = order.user.score + 1
# order.user.save()
return APIResponse(code=0, msg='取消成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')

View File

@ -0,0 +1,15 @@
# Create your views here.
from rest_framework.decorators import api_view
from myapp.handler import APIResponse
from myapp.models import Tag
from myapp.serializers import TagSerializer
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
tags = Tag.objects.all().order_by('-create_time')
serializer = TagSerializer(tags, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)

View File

@ -0,0 +1,264 @@
# Create your views here.
from django.db import connection
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.handler import APIResponse
from myapp.models import Classification, Thing, Tag, User
from myapp.serializers import ThingSerializer, ClassificationSerializer, ListThingSerializer, DetailThingSerializer, \
UpdateThingSerializer
from myapp.utils import dict_fetchall
@api_view(['GET'])
def list_api(request):
if request.method == 'GET':
keyword = request.GET.get("keyword", None)
c = request.GET.get("c", None)
tag = request.GET.get("tag", None)
sort = request.GET.get("sort", 'recent')
# 排序方式
order = '-create_time'
if sort == 'recent':
order = '-create_time'
elif sort == 'hot' or sort == 'recommend':
order = '-pv'
if keyword:
things = Thing.objects.filter(title__contains=keyword).filter(status='0').order_by(order)
# todo
elif c and int(c) > -1:
ids = [c]
things = Thing.objects.filter(classification_id__in=ids).filter(status='0').order_by(order)
elif tag:
tag = Tag.objects.get(id=tag)
print(tag)
things = tag.thing_set.all().filter(status='0').order_by(order)
else:
things = Thing.objects.all().defer('wish').filter(status='0').order_by(order)
serializer = ListThingSerializer(things, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['GET'])
def detail(request):
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
thing.pv = thing.pv + 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '对象不存在')
return APIResponse(code=1, msg='对象不存在')
if request.method == 'GET':
serializer = ThingSerializer(thing)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
def increaseWishCount(request):
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
# wish_count加1
thing.wish_count = thing.wish_count + 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '对象不存在')
return APIResponse(code=1, msg='对象不存在')
serializer = ThingSerializer(thing)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
@api_view(['POST'])
def increaseRecommendCount(request):
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
# recommend_count加1
thing.recommend_count = thing.recommend_count + 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '对象不存在')
return APIResponse(code=1, msg='对象不存在')
serializer = ThingSerializer(thing)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
@api_view(['POST'])
def addWishUser(request):
try:
username = request.GET.get('username', None)
thingId = request.GET.get('thingId', None)
if username and thingId:
user = User.objects.get(username=username)
thing = Thing.objects.get(pk=thingId)
if user not in thing.wish.all():
thing.wish.add(user)
thing.wish_count += 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '操作失败')
return APIResponse(code=1, msg='操作失败')
serializer = ThingSerializer(thing)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
@api_view(['POST'])
def removeWishUser(request):
try:
username = request.GET.get('username', None)
thingId = request.GET.get('thingId', None)
if username and thingId:
user = User.objects.get(username=username)
thing = Thing.objects.get(pk=thingId)
if user in thing.wish.all():
thing.wish.remove(user)
thing.wish_count -= 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '操作失败')
return APIResponse(code=1, msg='操作失败')
return APIResponse(code=0, msg='操作成功')
@api_view(['GET'])
def getWishThingList(request):
try:
username = request.GET.get('username', None)
if username:
user = User.objects.get(username=username)
things = user.wish_things.all()
serializer = ListThingSerializer(things, many=True)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
else:
return APIResponse(code=1, msg='username不能为空')
except Exception as e:
utils.log_error(request, '操作失败' + str(e))
return APIResponse(code=1, msg='获取心愿单失败')
@api_view(['POST'])
def addCollectUser(request):
try:
username = request.GET.get('username', None)
thingId = request.GET.get('thingId', None)
if username and thingId:
user = User.objects.get(username=username)
thing = Thing.objects.get(pk=thingId)
if user not in thing.collect.all():
thing.collect.add(user)
thing.collect_count += 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '操作失败')
return APIResponse(code=1, msg='操作失败')
serializer = DetailThingSerializer(thing)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
@api_view(['POST'])
def removeCollectUser(request):
try:
username = request.GET.get('username', None)
thingId = request.GET.get('thingId', None)
if username and thingId:
user = User.objects.get(username=username)
thing = Thing.objects.get(pk=thingId)
if user in thing.collect.all():
thing.collect.remove(user)
thing.collect_count -= 1
thing.save()
except Thing.DoesNotExist:
utils.log_error(request, '操作失败')
return APIResponse(code=1, msg='操作失败')
return APIResponse(code=0, msg='操作成功')
@api_view(['GET'])
def getCollectThingList(request):
try:
username = request.GET.get('username', None)
if username:
user = User.objects.get(username=username)
things = user.collect_things.all()
serializer = ListThingSerializer(things, many=True)
return APIResponse(code=0, msg='操作成功', data=serializer.data)
else:
return APIResponse(code=1, msg='username不能为空')
except Exception as e:
utils.log_error(request, '操作失败' + str(e))
return APIResponse(code=1, msg='获取收藏失败')
@api_view(['GET'])
def list_user_thing_api(request):
if request.method == 'GET':
user = request.GET.get("user", None)
if user:
things = Thing.objects.filter(user=user)
serializer = ListThingSerializer(things, many=True)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
return APIResponse(code=1, msg='user不能为空')
@api_view(['POST'])
def create(request):
data = request.data.copy()
data['status'] = '1'
serializer = ThingSerializer(data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='创建失败')
@api_view(['POST'])
def update(request):
try:
pk = request.GET.get('id', -1)
thing = Thing.objects.get(pk=pk)
except Thing.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
serializer = UpdateThingSerializer(thing, data=request.data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='查询成功', data=serializer.data)
else:
print(serializer.errors)
utils.log_error(request, '参数错误')
return APIResponse(code=1, msg='更新失败')

View File

@ -0,0 +1,162 @@
# Create your views here.
import datetime
from rest_framework.decorators import api_view, authentication_classes
from myapp import utils
from myapp.auth.authentication import TokenAuthtication
from myapp.handler import APIResponse
from myapp.models import User
from myapp.serializers import UserSerializer, LoginLogSerializer
from myapp.utils import md5value
def make_login_log(request):
try:
username = request.data['username']
data = {
"username": username,
"ip": utils.get_ip(request),
"ua": utils.get_ua(request)
}
serializer = LoginLogSerializer(data=data)
if serializer.is_valid():
serializer.save()
else:
print(serializer.errors)
except Exception as e:
print(e)
@api_view(['POST'])
def login(request):
username = request.data['username']
password = utils.md5value(request.data['password'])
users = User.objects.filter(username=username, password=password)
if len(users) > 0:
user = users[0]
if user.role in ['1', '3']:
return APIResponse(code=1, msg='该帐号为后台管理员帐号')
data = {
'username': username,
'password': password,
'token': md5value(username) # 生成令牌
}
serializer = UserSerializer(user, data=data)
if serializer.is_valid():
serializer.save()
make_login_log(request)
return APIResponse(code=0, msg='登录成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='用户名或密码错误')
@api_view(['POST'])
def register(request):
print(request.data)
username = request.data.get('username', None)
password = request.data.get('password', None)
repassword = request.data.get('repassword', None)
if not username or not password or not repassword:
return APIResponse(code=1, msg='用户名或密码不能为空')
if password != repassword:
return APIResponse(code=1, msg='密码不一致')
users = User.objects.filter(username=username)
if len(users) > 0:
return APIResponse(code=1, msg='该用户名已存在')
data = {
'username': username,
'password': password,
'role': 2, # 角色2
'status': 0,
}
data.update({'password': utils.md5value(request.data['password'])})
serializer = UserSerializer(data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='创建成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='创建失败')
@api_view(['GET'])
def info(request):
if request.method == 'GET':
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
serializer = UserSerializer(user)
return APIResponse(code=0, msg='查询成功', data=serializer.data)
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def update(request):
try:
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
except User.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
data = request.data.copy()
if 'username' in data.keys():
del data['username']
if 'password' in data.keys():
del data['password']
if 'role' in data.keys():
del data['role']
serializer = UserSerializer(user, data=data)
print(serializer.is_valid())
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')
@api_view(['POST'])
@authentication_classes([TokenAuthtication])
def updatePwd(request):
try:
pk = request.GET.get('id', -1)
user = User.objects.get(pk=pk)
except User.DoesNotExist:
return APIResponse(code=1, msg='对象不存在')
print(user.role)
if user.role != '2':
return APIResponse(code=1, msg='参数非法')
password = request.data.get('password', None)
newPassword1 = request.data.get('newPassword1', None)
newPassword2 = request.data.get('newPassword2', None)
if not password or not newPassword1 or not newPassword2:
return APIResponse(code=1, msg='不能为空')
if user.password != utils.md5value(password):
return APIResponse(code=1, msg='原密码不正确')
if newPassword1 != newPassword2:
return APIResponse(code=1, msg='两次密码不一致')
data = request.data.copy()
data.update({'password': utils.md5value(newPassword1)})
serializer = UserSerializer(user, data=data)
if serializer.is_valid():
serializer.save()
return APIResponse(code=0, msg='更新成功', data=serializer.data)
else:
print(serializer.errors)
return APIResponse(code=1, msg='更新失败')

92
server/readme.md Normal file
View File

@ -0,0 +1,92 @@
### 后端部署步骤
> 部署过程中如遇问题可咨询作者lengqin1024微信
1. 安装mysql数据库启动服务
2. 打开cmd命令行进入mysql并新建数据库
```
mysql -u root -p
CREATE DATABASE IF NOT EXISTS python_jiajiao DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
```
3. 恢复sql数据
```
use xxx
source xxxx.sql
```
4. 修改settings.py中的配置信息
5. 复制资源将upload文件夹复制到server目录下
6. 安装python 3.8
7. 安装依赖包
```
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
```
运行项目
```
python manage.py runserver 0.0.0.0:9003
```
7. 后期维护改动
将修改的py文件覆盖服务器的py文件即可重启django
### 删除数据库
drop database if exists xxx;
### 创建数据库
CREATE DATABASE IF NOT EXISTS xxx DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
### 迁移数据库表
```
python manage.py makemigrations;
python manage.py migrate;
python manage.py makemigrations myapp;
python manage.py migrate myapp;
```
### 跨域配置
django-cors-headers
### 多对多技术参考
https://www.cnblogs.com/SunshineKimi/p/14140900.html
### 二级分类设计
https://blog.csdn.net/weixin_47971206/article/details/124199978
### 常见问题
多对多的查询可通过related_name别名查询
join查询
ForeignKey的时候字段会自动加_id后缀
学习SerializerMethodField
跨域配置 django-cors-headers
数据库备份命令:
mysqldump -u root -p --databases 数据库名称 > xxx.sql
数据库还原命令:
source D:/xxx/xxx/shop.sql;
创建管理员命令:
insert into b_user(username,password,role,status) values('admin111',md5('admin111'),1,'0');
接口请求频次限制
### 登录接口
调login -> 生成token
### 注意
update接口的时候如果model里面存在多对多字段则需要设置explode

6
server/requirements.txt Normal file
View File

@ -0,0 +1,6 @@
Django==3.2.11
PyMySQL==1.0.2
djangorestframework==3.13.0
django-cors-headers==3.13.0
Pillow==9.1.1
psutil==5.9.4

View File

@ -0,0 +1,4 @@
import pymysql
pymysql.install_as_MySQLdb()
print("===============install pymysql==============")

16
server/server/asgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
ASGI config for server project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
application = get_asgi_application()

150
server/server/settings.py Normal file
View File

@ -0,0 +1,150 @@
"""
Django settings for server project.
Generated by 'django-admin startproject' using Django 4.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
# BASE_DIR = Path(__file__).resolve().parent.parent
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-sz@madp0ifx!b)^lg_g!f+5s*w7w_=sjgq-k+erzb%x42$^r!d'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders', # 跨域
'myapp'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # 跨域配置
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'myapp.middlewares.LogMiddleware.OpLogs'
]
CORS_ORIGIN_ALLOW_ALL = True # 允许跨域
ROOT_URLCONF = 'server.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
WSGI_APPLICATION = 'server.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'python_jiajiao',
'USER': 'root',
'PASSWORD': '4643830',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
}
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
# 时区
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# 日期时间格式
DATE_FORMAT = 'Y-m-d'
DATETIME_FORMAT = 'Y-m-d H:i:s'
# 上传文件路径
# 并在urls.py配置+static
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload/')
MEDIA_URL = '/upload/'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# 跨域配置
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = '*'

25
server/server/urls.py Normal file
View File

@ -0,0 +1,25 @@
"""server URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from server import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('myapp/', include('myapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

16
server/server/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for server project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings')
application = get_wsgi_application()

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
server/upload/cover/1.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
server/upload/cover/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
server/upload/cover/10.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
server/upload/cover/11.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
server/upload/cover/12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
server/upload/cover/13.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
server/upload/cover/14.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
server/upload/cover/15.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
server/upload/cover/16.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Some files were not shown because too many files have changed in this diff Show More