fix: S-01反模式清扫收尾(opt_id归一化+music分页钳制+visitors外键归一化)
This commit is contained in:
@@ -11,7 +11,7 @@ from rest_framework.permissions import AllowAny, IsAuthenticated
|
|||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from apps.videos.models import Video
|
from apps.videos.models import Video
|
||||||
from core.api import render_data
|
from core.api import opt_id, render_data
|
||||||
|
|
||||||
from .models import VideoPlayStat
|
from .models import VideoPlayStat
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ class PlayStatReportView(APIView):
|
|||||||
|
|
||||||
async def post(self, request):
|
async def post(self, request):
|
||||||
try:
|
try:
|
||||||
video_id = int(request.data.get("video_id") or 0)
|
video_id = opt_id(request.data.get("video_id"))
|
||||||
watch_seconds = float(request.data.get("watch_seconds") or 0.0)
|
watch_seconds = float(request.data.get("watch_seconds") or 0.0)
|
||||||
duration = float(request.data.get("duration") or 0.0)
|
duration = float(request.data.get("duration") or 0.0)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from .serializers import (
|
|||||||
MessageSerializer,
|
MessageSerializer,
|
||||||
SystemMessageSerializer,
|
SystemMessageSerializer,
|
||||||
)
|
)
|
||||||
from core.api import paginate_cursor, parse_page_size, render_data
|
from core.api import opt_id, paginate_cursor, parse_page_size, render_data
|
||||||
|
|
||||||
|
|
||||||
def _channel_layer():
|
def _channel_layer():
|
||||||
@@ -138,10 +138,7 @@ class ConversationListCreateView(APIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def post(self, request):
|
async def post(self, request):
|
||||||
try:
|
peer_id = opt_id(request.data.get("peer_id"))
|
||||||
peer_id = int(request.data.get("peer_id") or 0)
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
return Response({"detail": "invalid peer"}, status=400)
|
|
||||||
if not peer_id or peer_id == request.user.id:
|
if not peer_id or peer_id == request.user.id:
|
||||||
return Response({"detail": "invalid peer"}, status=400)
|
return Response({"detail": "invalid peer"}, status=400)
|
||||||
a, b = sorted([request.user.id, peer_id])
|
a, b = sorted([request.user.id, peer_id])
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from rest_framework import status
|
|||||||
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated
|
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.api import render_data
|
from core.api import opt_id, render_data
|
||||||
|
|
||||||
from .models import Report, SensitiveWord
|
from .models import Report, SensitiveWord
|
||||||
from .serializers import ReportCreateSerializer, ReportSerializer, SensitiveWordSerializer
|
from .serializers import ReportCreateSerializer, ReportSerializer, SensitiveWordSerializer
|
||||||
@@ -122,7 +122,7 @@ class AdminAuditView(APIView):
|
|||||||
permission_classes = [IsAdminUser]
|
permission_classes = [IsAdminUser]
|
||||||
|
|
||||||
async def post(self, request):
|
async def post(self, request):
|
||||||
report_id = int(request.data.get("report_id") or 0)
|
report_id = opt_id(request.data.get("report_id"))
|
||||||
action = request.data.get("action") # "hide", "delete", "reject"
|
action = request.data.get("action") # "hide", "delete", "reject"
|
||||||
note = request.data.get("note", "")
|
note = request.data.get("note", "")
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class MusicListView(APIView):
|
|||||||
|
|
||||||
async def get(self, request):
|
async def get(self, request):
|
||||||
q = (request.query_params.get("q") or "").strip()
|
q = (request.query_params.get("q") or "").strip()
|
||||||
page_size = min(max(int(request.query_params.get("page_size") or 20), 1), 50)
|
page_size = parse_page_size(request.query_params.get("page_size"))
|
||||||
qs = Music.objects.all().order_by("-use_count", "-id")
|
qs = Music.objects.all().order_by("-use_count", "-id")
|
||||||
if q:
|
if q:
|
||||||
qs = qs.filter(Q(title__icontains=q) | Q(artist__icontains=q))
|
qs = qs.filter(Q(title__icontains=q) | Q(artist__icontains=q))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from adrf.views import APIView
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.api import paginate_cursor, parse_page_size, render_data
|
from core.api import opt_id, paginate_cursor, parse_page_size, render_data
|
||||||
|
|
||||||
from .models import Visit
|
from .models import Visit
|
||||||
from .serializers import VisitSerializer
|
from .serializers import VisitSerializer
|
||||||
@@ -17,15 +17,15 @@ class VisitView(APIView):
|
|||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
async def post(self, request):
|
async def post(self, request):
|
||||||
owner_id = int(request.data.get("owner_id") or 0)
|
owner_id = opt_id(request.data.get("owner_id"))
|
||||||
if not owner_id or owner_id == request.user.id:
|
if not owner_id or owner_id == request.user.id:
|
||||||
return Response({"detail": "invalid owner"}, status=400)
|
return Response({"detail": "invalid owner"}, status=400)
|
||||||
video_id = request.data.get("video_id")
|
video_id = opt_id(request.data.get("video_id"))
|
||||||
source = request.data.get("source", "profile")[:32]
|
source = request.data.get("source", "profile")[:32]
|
||||||
await Visit.objects.acreate(
|
await Visit.objects.acreate(
|
||||||
visitor=request.user,
|
visitor=request.user,
|
||||||
owner_id=owner_id,
|
owner_id=owner_id,
|
||||||
video_id=video_id,
|
video_id=video_id or None,
|
||||||
source=source,
|
source=source,
|
||||||
)
|
)
|
||||||
return Response({"status": "recorded"})
|
return Response({"status": "recorded"})
|
||||||
|
|||||||
@@ -31,6 +31,18 @@ def parse_page_size(raw: Any, default: int = DEFAULT_PAGE_SIZE, maximum: int = M
|
|||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def opt_id(raw: Any, default: int = 0) -> int:
|
||||||
|
"""归一化外部 id:非正整数一律回落 default,绝不抛 ValueError 进 500。
|
||||||
|
|
||||||
|
S-01 反模式清扫:外部 id 必须经此函数再进 ORM,禁止 int() 裸调用。
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
v = int(raw)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return default
|
||||||
|
return v if v > 0 else default
|
||||||
|
|
||||||
|
|
||||||
async def paginate_cursor(
|
async def paginate_cursor(
|
||||||
qs,
|
qs,
|
||||||
cursor: Any,
|
cursor: Any,
|
||||||
|
|||||||
Reference in New Issue
Block a user