forked from kongfp/TP_Admin
31
0
Fork 1

Compare commits

..

No commits in common. 'master' and 'master' have entirely different histories.

5
.gitignore vendored

@ -1,8 +1,7 @@
.DS_Store
node_modules
/dist
.idea
__pycache__
# local env files
.env.local
@ -22,5 +21,3 @@ pnpm-debug.log*
*.njsproj
*.sln
*.sw?
*.log
db.sqlite3

@ -1,33 +0,0 @@
# 建立 python 3.7环境
FROM python:3.7
# 安装netcat
RUN apt-get update && apt install -y netcat
# 可选:设置镜像源为国内
COPY pip.conf /root/.pip/pip.conf
# 容器内创建 myproject 文件夹
ENV APP_HOME=/home/myproject
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
# 将当前目录加入到工作目录中(. 表示当前目录)
ADD . $APP_HOME
# 更新pip版本
RUN /usr/local/bin/python -m pip install --upgrade pip
# 安装项目依赖
RUN pip install -r requirements.txt
# 移除\r in windows
RUN sed -i 's/\r//' ./start.sh
# 给start.sh可执行权限
RUN chmod +x ./start.sh
EXPOSE 8000
# 数据迁移并使用uwsgi启动服务
ENTRYPOINT /bin/bash ./start.sh

@ -1,5 +1,5 @@
"""
ASGI config for TP_API project.
ASGI config for TP_Admin project.
It exposes the ASGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_API.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_Admin.settings')
application = get_asgi_application()

@ -1,5 +1,5 @@
"""
Django settings for TP_API project.
Django settings for TP_Admin project.
Generated by 'django-admin startproject' using Django 3.2.19.
@ -11,7 +11,6 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -21,12 +20,12 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-kqm6r(-!q-emw5c!!@dc)9l^hm@m#4!)-d7ecq85&u^5leu5)_'
SECRET_KEY = 'django-insecure-d@xkg+%-m3g_h!%howm1%u#1l*v&sd3=7&_-33w!(oy7#!hg79'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
DEBUG = True
ALLOWED_HOSTS = ["*"]
ALLOWED_HOSTS = []
# Application definition
@ -38,16 +37,12 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_filters',
'corsheaders',
'app',
'app.apps.AppConfig',
]
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',
@ -55,12 +50,13 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'TP_API.urls'
ROOT_URLCONF = 'TP_Admin.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
@ -73,7 +69,7 @@ TEMPLATES = [
},
]
WSGI_APPLICATION = 'TP_API.wsgi.application'
WSGI_APPLICATION = 'TP_Admin.wsgi.application'
# Database
@ -109,15 +105,15 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Shanghai'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = False
USE_TZ = True
# Static files (CSS, JavaScript, Images)
@ -125,86 +121,7 @@ USE_TZ = False
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# 解决跨域
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = ["*"]
CORS_ORIGIN_WHITELIST = ()
# 对应的发送的请求的跨域
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
USE_L10N = False
DATE_FORMAT = 'Y-m-d'
DATETIME_FORMAT = 'Y-m-d H:M:S'
REST_FRAMEWORK = {
'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",
'DATE_FORMAT': "%Y-%m-%d",
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'EXCEPTION_HANDLER': 'app.exception.exception_handler',
}
# 配置日志
LOG_DIR = os.path.join(BASE_DIR, 'logs/')
LOGGING = {
'version': 1, # 保留字
'disable_existing_loggers': False, # 是否禁用已经存在的日志实例
'formatters': { # 定义日志的格式
'standard': {
'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
'[%(levelname)s][%(message)s]'
},
'simple': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
'collect': {
'format': '%(message)s'
}
},
'filters': { # 定义日志的过滤器
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理程序
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'], # 只有在Django debug为True时才在屏幕打印日志
'class': 'logging.StreamHandler',
'formatter': 'simple',
# 'filename': os.path.join(BASE_LOG_DIR, "tpservice.log")
},
'file': {
'level': 'DEBUG',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(LOG_DIR, 'debug.log'), # 日志文件
'when': "D",
'interval': 1,
'formatter': 'standard'
},
},
'loggers': { # 日志实例 记录器
'mylogger': { # 默认的logger应用如下配置
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': True, # 是否向上一级logger实例传递日志信息
},
},
}

@ -1,4 +1,4 @@
"""TP_Api URL Configuration
"""TP_Admin URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
@ -13,14 +13,9 @@ 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.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from app import views
router = DefaultRouter()
router.register('', views.ModelQuery)
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('', include(router.urls)),
path('admin/', admin.site.urls),
]

@ -1,5 +1,5 @@
"""
WSGI config for TP_API project.
WSGI config for TP_Admin project.
It exposes the WSGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_API.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_Admin.settings')
application = get_wsgi_application()

@ -1,240 +0,0 @@
# TP后台接口文档
<details>
<summary>条件查询</summary>
- 请求方式GET
- 请求链接http://127.0.0.1:8002/api/
- 请求参数:
| 参数名 | 参数值 | 是否必填 | 参数类型 | 描述说明 |
| ----------- |---------------------| -------- |--------| ---------- |
| record_time | 2023-05-26 13:09:05 | 否 | string | 记录仪时间 |
| police_id | 00000001 | 否 | string | 警号 |
| event_type | 0 | 否 | string | 事件类型 |
- 可选参数:
| 参数名 | 参数值 | 是否必填 | 参数类型 | 描述说明 |
| --------- | ------ | -------- | -------- | -------------------- |
| page | 1 | 否 | string | 页码 |
| page_size | 20 | 否 | string | 页面大小(每页条数) |
- 返回值:
| 参数名 | 参数值 | 参数类型 | 描述说明 |
| ------------- | ------------------------------------------------- | -------- | ------------------------ |
| uid | 1 | int | 自增 |
| video_hash | 38fb463b135fa12534104f85492cc6f1 | string | 视频哈希值 |
| record_time | 2023-05-26 13:09:05 | string | 记录仪时间 |
| police_id | 00000001 | string | 警号 |
| event_type | 1 | string | 事件类型 |
| is_violation | true | bool | 是否违规 |
| small_image | http://192.168.0.47:8000/media/images/0000609.jpg | string | 缩略图 |
| relative_time | 4.0 | float | 相对时间 |
| video_dir | http://192.168.0.47:8000/media/video/B1.MP4 | string | 视频地址 |
| car_number | 苏a045689 | string | 车牌号 |
| ai_analysis | 违规 | string | 分析结果 |
| add_time | 2023-05-31 18:42:15 | string | 记录添加时间(自动添加) |
| update_time | 2023-05-31 18:42:15 | string | 记录更新时间(自动添加) |
| is_display | true | bool | 是否展示(自动添加) |
</details>
<details>
<summary>查询所有</summary>
- 请求方式GET
- 请求链接http://127.0.0.1:8002/api/
- 可选参数:
| 参数名 | 参数值 | 是否必填 | 参数类型 | 描述说明 |
| --------- | ------ | -------- | -------- | -------------------- |
| page | 1 | 否 | string | 页码 |
| page_size | 20 | 否 | string | 页面大小(每页条数) |
- 返回值
| 参数名 | 参数值 | 参数类型 | 描述说明 |
| ------------- | ------------------------------------------------- | -------- | ------------------------ |
| uid | 1 | int | 自增 |
| video_hash | 38fb463b135fa12534104f85492cc6f1 | string | 视频哈希值 |
| record_time | 2023-05-26 13:09:05 | string | 记录仪时间 |
| police_id | 00000001 | string | 警号 |
| event_type | 1 | string | 事件类型 |
| is_violation | true | bool | 是否违规 |
| small_image | http://192.168.0.47:8000/media/images/0000609.jpg | string | 缩略图 |
| relative_time | 4.0 | float | 相对时间 |
| video_dir | http://192.168.0.47:8000/media/video/B1.MP4 | string | 视频地址 |
| car_number | 苏a045689 | string | 车牌号 |
| ai_analysis | 违规 | string | 分析结果 |
| add_time | 2023-05-31 18:42:15 | string | 记录添加时间(自动添加) |
| update_time | 2023-05-31 18:42:15 | string | 记录更新时间(自动添加) |
| is_display | true | bool | 是否展示(自动添加) |
</details>
<details>
<summary>新增数据</summary>
- 请求方式POST
- 请求链接http://127.0.0.1:8002/api/
- 请求body
```json
{
"video_hash": "vbhdrbvcw",
"record_time": "2023-05-26 13:09:05",
"police_id": "00000002",
"event_type": "1",
"is_violation": true,
"small_image": "nvikefrooiwer",
"relative_time": 4.0,
"video_dir": "/d/test",
"car_number": "苏a045689",
"ai_analysis": "违规"
}
```
| 参数名 | 参数值 | 是否必填 | 参数类型 | 描述说明 |
| ------------- |---------------------| -------- |----------| ------ |
| video_hash | vbhdrbvcw | 是 | string | 视频哈希 |
| record_time | 2023-05-26 13:09:05 | 是 | datetime | 记录仪时间 |
| police_id | 00000002 | 是 | string | 警号 |
| event_type | 1 | 是 | string | 事件类型 |
| is_violation | true | 是 | bool | 是否违规 |
| small_image | nvikefrooiwer | 是 | string | 缩略图 |
| relative_time | 4.0 | 是 | int | 相对时间 |
| video_dir | /d/test | 是 | string | 视频路径 |
| car_number | 苏a045689 | 是 | string | 车牌号 |
| ai_analysis | 违规 | 是 | string | 分析结果 |
- 返回值
| 参数名 | 参数值 | 参数类型 | 描述说明 |
| ------------- | ------------------------------------------------- | -------- | ------------------------ |
| uid | 1 | int | 自增 |
| video_hash | 38fb463b135fa12534104f85492cc6f1 | string | 视频哈希值 |
| record_time | 2023-05-26 13:09:05 | string | 记录仪时间 |
| police_id | 00000001 | string | 警号 |
| event_type | 1 | string | 事件类型 |
| is_violation | true | bool | 是否违规 |
| small_image | http://192.168.0.47:8000/media/images/0000609.jpg | string | 缩略图 |
| relative_time | 4.0 | float | 相对时间 |
| video_dir | http://192.168.0.47:8000/media/video/B1.MP4 | string | 视频地址 |
| car_number | 苏a045689 | string | 车牌号 |
| ai_analysis | 违规 | string | 分析结果 |
| add_time | 2023-05-31 18:42:15 | string | 记录添加时间(自动添加) |
| update_time | 2023-05-31 18:42:15 | string | 记录更新时间(自动添加) |
| is_display | true | bool | 是否展示(自动添加) |
</details>
<details>
<summary>修改数据</summary>
- 请求方式put
- 请求链接http://127.0.0.1:8002/api/20/
- 请求body
```json
{
"video_hash": "vbhdrbvcw",
"record_time": "2023-05-26 13:09:05",
"police_id": "00000002",
"event_type": "1",
"is_violation": true,
"small_image": "nvikefrooiwer",
"relative_time": 4.0,
"video_dir": "/d/test",
"car_number": "苏a045689",
"ai_analysis": "违规"
}
```
| 参数名 | 参数值 | 是否必填 | 参数类型 | 描述说明 |
| ------------- |---------------------| -------- |-----|-------|
| video_hash | vbhdrbvcw | 是 | string | 视频哈希 |
| record_time | 2023-05-26 13:09:05 | 是 | string | 记录仪时间 |
| police_id | 00000002 | 是 | string | 警号 |
| event_type | 1 | 是 | string | 事件类型 |
| is_violation | true | 是 | bool | 是否违规 |
| small_image | nvikefrooiwer | 是 | string | 缩略图 |
| relative_time | 4.0 | 是 | float | 相对时间 |
| video_dir | /d/test | 是 | string | 视频路径 |
| car_number | 苏a045689 | 是 | string | 车牌号 |
| ai_analysis | 违规 | 是 | string | 分析结果 |
- 备注操作会修改uid为20的数据
- 返回值:
| 参数名 | 参数值 | 参数类型 | 描述说明 |
| ------------- | ------------------------------------------------- | -------- | ---------------------- |
| uid | 1 | int | 自增 |
| video_hash | 38fb463b135fa12534104f85492cc6f1 | string | 视频哈希值 |
| record_time | 2023-05-26 13:09:05 | string | 记录仪时间 |
| police_id | 00000001 | string | 警号 |
| event_type | 1 | string | 事件类型 |
| is_violation | true | bool | 是否违规 |
| small_image | http://192.168.0.47:8000/media/images/0000609.jpg | string | 缩略图 |
| relative_time | 4.0 | float | 相对时间 |
| video_dir | http://192.168.0.47:8000/media/video/B1.MP4 | string | 视频地址 |
| car_number | 苏a045689 | string | 车牌号 |
| ai_analysis | 违规 | string | 分析结果 |
| add_time | 2023-05-31 18:42:15 | string | 记录添加时间(自动添加) |
| update_time | 2023-05-31 18:42:15 | string | 记录更新时间(自动添加) |
| is_display | true | bool | 是否展示(自动添加) |
</details>
<details>
<summary>删除数据</summary>
- 请求方式delete
- 请求链接http://127.0.0.1:8002/api/20/
- 备注操作会删除uid为20的数据
- 返回值:
| 参数名 | 参数值 | 参数类型 | 描述说明 |
| ------------- | ------------------------------------------------- | -------- | ------------------------ |
| uid | 1 | int | 自增 |
| video_hash | 38fb463b135fa12534104f85492cc6f1 | string | 视频哈希值 |
| record_time | 2023-05-26 13:09:05 | string | 记录仪时间 |
| police_id | 00000001 | string | 警号 |
| event_type | 1 | string | 事件类型 |
| is_violation | true | bool | 是否违规 |
| small_image | http://192.168.0.47:8000/media/images/0000609.jpg | string | 缩略图 |
| relative_time | 4.0 | float | 相对时间 |
| video_dir | http://192.168.0.47:8000/media/video/B1.MP4 | string | 视频地址 |
| car_number | 苏a045689 | string | 车牌号 |
| ai_analysis | 违规 | string | 分析结果 |
| add_time | 2023-05-31 18:42:15 | string | 记录添加时间(自动添加) |
| update_time | 2023-05-31 18:42:15 | string | 记录更新时间(自动添加) |
| is_display | true | bool | 是否展示(自动添加) |
</details>

@ -1,5 +1,3 @@
from django.contrib import admin
# Register your models here.
from app.models import TP
admin.site.register(TP)

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

@ -1,23 +0,0 @@
import logging
from rest_framework.views import exception_handler as drf_exception_handler # drf原生处理异常函数取别名
from rest_framework.views import Response
from rest_framework import status
logger = logging.getLogger('mylogger')
def exception_handler(exc, context):
# drf的exception_handler做基础处理
response = drf_exception_handler(exc, context)
# 为空,进行自定义二次处理
logger.error(str(exc))
if response is None:
# print(exc) # 错误原因
# print(context) # 错误信息
# print('%s - %s - %s' % (context['view'], context['request'].method, exc))
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response

@ -1,42 +1,3 @@
from django.db import models
# Create your models here.
class TP(models.Model):
# uid
uid = models.AutoField(primary_key=True)
# 视频哈希
video_hash = models.CharField(max_length=50, verbose_name='视频哈希')
# 记录仪时间
record_time = models.DateTimeField(verbose_name='记录仪时间')
# 警号
police_id = models.CharField(max_length=50, null=True, blank=True, verbose_name='警号') # 警号可为空可不传
# 事件类型
event_type = models.CharField(max_length=50, verbose_name='事件类型')
# 是否违规
is_violation = models.BooleanField(verbose_name='是否违规')
# 缩略图
small_image = models.CharField(max_length=100, verbose_name='缩略图')
# 相对时间
relative_time = models.FloatField(verbose_name='相对时间')
# 视频路径
video_dir = models.CharField(max_length=100, verbose_name='视频路径')
# 车牌号
car_number = models.CharField(max_length=50, verbose_name='车牌号', null=True, blank=True) # 车牌可为空可不传
# 分析结果
ai_analysis = models.CharField(max_length=255, verbose_name='分析结果', null=True, blank=True) # 分析结果可为空可不传
# 加入时间
add_time = models.DateTimeField(auto_now_add=True, verbose_name='加入时间')
# 更新时间
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
# 是否显示
is_display = models.BooleanField(default=True, verbose_name='是否显示')
class Meta:
db_table = "app_tp"
# 排序 uid倒序
ordering = ['-uid']

@ -1,9 +0,0 @@
from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 10
page_query_param = "page"
page_size_query_param = "page_size"
max_page_size = 100

@ -1,35 +0,0 @@
from rest_framework import serializers
from django_filters.rest_framework import FilterSet
import django_filters
from app.models import TP
class SerialMyModel(serializers.ModelSerializer):
class Meta:
model = TP
fields = "__all__"
class SerialFilter(FilterSet):
"""
过滤器支持模糊查询
record_time日期时间格式 2023-01-01 00:00:00
police_id支持模糊匹配
event_type支持模糊匹配
"""
record_time = django_filters.DateTimeFilter(field_name='record_time', lookup_expr='icontains')
police_id = django_filters.CharFilter(field_name='police_id', lookup_expr='icontains')
event_type = django_filters.CharFilter(field_name='event_type', lookup_expr='icontains')
# 记录时间范围查询
start_time = django_filters.DateTimeFilter(field_name='record_time', lookup_expr='gte')
end_time = django_filters.DateTimeFilter(field_name='record_time', lookup_expr='lte')
class Meta:
# 指定模型
models = TP
# 指定需要模糊查询的字段
fields = ("record_time", "police_id", "event_type",)

@ -1,20 +1,3 @@
from django.shortcuts import render
# Create your views here.
from rest_framework import viewsets
from rest_framework.response import Response
from app.models import TP
from app.serializers import SerialMyModel, SerialFilter
from app.pagination import MyPageNumberPagination
class ModelQuery(viewsets.ModelViewSet):
# 查询类
queryset = TP.objects.all().order_by("-uid") # 按照uid倒序
# 序列化类
serializer_class = SerialMyModel
# 分页类
pagination_class = MyPageNumberPagination
# 条件筛选
filterset_class = SerialFilter

@ -6,7 +6,7 @@ import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_API.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TP_Admin.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:

@ -1,6 +0,0 @@
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn
[list]
format=columns

Binary file not shown.

@ -1,9 +0,0 @@
#!/bin/bash
python manage.py makemigrations&&
python manage.py migrate&&
uwsgi --ini /home/myproject/uwsgi.ini&&
echo 'TP项目启动完成'
tail -f /dev/null
exec "$@"

@ -1,38 +0,0 @@
[uwsgi]
project=myproject
uid=www-data
gid=www-data
base=/home
chdir=%(base)/%(project)
module=TP_API.wsgi:application
master=True
processes=2
http=0.0.0.0:8000
chown-socket=%(uid):www-data
chmod-socket=664
vacuum=True
max-requests=5000
pidfile=%(base)/%(project)/logs/%(project)-master.pid
daemonize=%(base)/%(project)/logs/%(project)-uwsgi.log
#设置一个请求的超时时间(秒),如果一个请求超过了这个时间,则请求被丢弃
harakiri = 60
post buffering = 8192
buffer-size= 65535
#当一个请求被harakiri杀掉会会输出一条日志
harakiri-verbose = true
#开启内存使用情况报告
memory-report = true
#设置平滑的重启(直到处理完接收到的请求)的长等待时间(秒)
reload-mercy = 10
#设置工作进程使用虚拟内存超过N MB就回收重启
reload-on-as= 1024
Loading…
Cancel
Save