commit
14
.gitignore
vendored
Normal 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
@ -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
@ -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
10
server/myapp/admin.py
Normal 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
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MyappConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'myapp'
|
5
server/myapp/auth/MyRateThrottle.py
Normal file
@ -0,0 +1,5 @@
|
||||
from rest_framework.throttling import AnonRateThrottle
|
||||
|
||||
|
||||
class MyRateThrottle(AnonRateThrottle):
|
||||
THROTTLE_RATES = {"anon": "5/min"}
|
0
server/myapp/auth/__init__.py
Normal file
46
server/myapp/auth/authentication.py
Normal 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
@ -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)
|
54
server/myapp/middlewares/LogMiddleware.py
Normal 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
|
0
server/myapp/middlewares/__init__.py
Normal file
222
server/myapp/models.py
Normal 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"
|
0
server/myapp/permission/__init__.py
Normal file
12
server/myapp/permission/permission.py
Normal 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
@ -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
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
101
server/myapp/urls.py
Normal 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
@ -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()
|
2
server/myapp/views/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from myapp.views.admin import *
|
||||
from myapp.views.index import *
|
14
server/myapp/views/admin/__init__.py
Normal 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 *
|
68
server/myapp/views/admin/ad.py
Normal 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='删除成功')
|
68
server/myapp/views/admin/banner.py
Normal 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='删除成功')
|
74
server/myapp/views/admin/classification.py
Normal 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='删除成功')
|
69
server/myapp/views/admin/comment.py
Normal 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='删除成功')
|
14
server/myapp/views/admin/errorLog.py
Normal 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)
|
60
server/myapp/views/admin/loginLog.py
Normal 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='删除成功')
|
68
server/myapp/views/admin/notice.py
Normal 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='删除成功')
|
14
server/myapp/views/admin/opLog.py
Normal 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)
|
147
server/myapp/views/admin/order.py
Normal 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='删除成功')
|
98
server/myapp/views/admin/overview.py
Normal 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)
|
53
server/myapp/views/admin/record.py
Normal 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='删除成功')
|
75
server/myapp/views/admin/tag.py
Normal 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='删除成功')
|
104
server/myapp/views/admin/thing.py
Normal 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='删除成功')
|
176
server/myapp/views/admin/user.py
Normal 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='删除成功')
|
8
server/myapp/views/index/__init__.py
Normal 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 *
|
87
server/myapp/views/index/address.py
Normal 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='删除成功')
|
21
server/myapp/views/index/classification.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
87
server/myapp/views/index/comment.py
Normal 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='推荐成功')
|
15
server/myapp/views/index/notice.py
Normal 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)
|
||||
|
85
server/myapp/views/index/order.py
Normal 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='更新失败')
|
15
server/myapp/views/index/tag.py
Normal 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)
|
||||
|
264
server/myapp/views/index/thing.py
Normal 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='更新失败')
|
162
server/myapp/views/index/user.py
Normal 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
@ -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
@ -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
|
4
server/server/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
import pymysql
|
||||
pymysql.install_as_MySQLdb()
|
||||
|
||||
print("===============install pymysql==============")
|
16
server/server/asgi.py
Normal 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
@ -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
@ -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
@ -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()
|
BIN
server/upload/ad/1674045266113.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/ad/1674045282581.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/ad/1674045308177.png
Normal file
After Width: | Height: | Size: 901 B |
BIN
server/upload/ad/1674045324510.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/ad/1684565423182.jpeg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
server/upload/ad/1684565863904.jpeg
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
server/upload/ad/1684565876995.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
server/upload/ad/1686369031223.jpeg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
server/upload/avatar/1676553050529.png
Normal file
After Width: | Height: | Size: 218 KiB |
BIN
server/upload/avatar/1676553366217.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
server/upload/avatar/1676553498600.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/avatar/1676553815688.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/avatar/1677240189427.png
Normal file
After Width: | Height: | Size: 901 B |
BIN
server/upload/avatar/1677982820781.jpeg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
server/upload/avatar/1679146350134.jpeg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
server/upload/avatar/1684593239449.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
server/upload/avatar/1684593453676.jpeg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
server/upload/banner/1673963977440.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/banner/1673964384835.png
Normal file
After Width: | Height: | Size: 901 B |
BIN
server/upload/banner/1673964652167.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/banner/1673965110189.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/banner/1673965198155.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/banner/1673965389141.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/banner/1673965574311.png
Normal file
After Width: | Height: | Size: 901 B |
BIN
server/upload/banner/1673965709533.jpeg
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
server/upload/banner/1673965718720.png
Normal file
After Width: | Height: | Size: 901 B |
BIN
server/upload/banner/1673965728690.jpeg
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
server/upload/cover/1.jpeg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
server/upload/cover/1.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
server/upload/cover/10.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
server/upload/cover/11.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
server/upload/cover/12.jpg
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
server/upload/cover/13.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
server/upload/cover/14.jpg
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
server/upload/cover/15.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
server/upload/cover/16.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
server/upload/cover/1672749055571.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/cover/1674044230851.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/cover/1676186518276.jpeg
Normal file
After Width: | Height: | Size: 784 KiB |
BIN
server/upload/cover/1676186872895.png
Normal file
After Width: | Height: | Size: 234 KiB |
BIN
server/upload/cover/1676186935002.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
server/upload/cover/1676188277099.png
Normal file
After Width: | Height: | Size: 292 KiB |
BIN
server/upload/cover/1676188355688.png
Normal file
After Width: | Height: | Size: 208 KiB |
BIN
server/upload/cover/1676381084256.png
Normal file
After Width: | Height: | Size: 218 KiB |
BIN
server/upload/cover/1676381091144.png
Normal file
After Width: | Height: | Size: 219 KiB |
BIN
server/upload/cover/1676381097051.png
Normal file
After Width: | Height: | Size: 208 KiB |
BIN
server/upload/cover/1676381103032.png
Normal file
After Width: | Height: | Size: 213 KiB |
BIN
server/upload/cover/1676381110015.png
Normal file
After Width: | Height: | Size: 234 KiB |
BIN
server/upload/cover/1677500674281.jpeg
Normal file
After Width: | Height: | Size: 40 KiB |