added prediction viewset to views.py

This commit is contained in:
afanasyev.aa 2025-07-02 04:32:44 +09:00
parent 7ee58ce501
commit 57fdcaa0e9
3 changed files with 88 additions and 81 deletions

View file

@ -1,28 +1,35 @@
from django.urls import path from django.urls import path
from .views import (PredictionCreateView, PredictionListView, from rest_framework.routers import DefaultRouter
PredictionHistoryListView, from rest_framework.authtoken.views import obtain_auth_token
PredictionHistoryDetailView, from .views import (
PredictionHistoryDeleteView, PredictionViewSet,
SessionView,
WhoAmIView,
SavedPointViewset, SavedPointViewset,
TelemetryListCreateView,
get_csrf, get_csrf,
login_view, login_view,
logout_view) logout_view,
from rest_framework.authtoken.views import obtain_auth_token SessionView,
from .views import TelemetryListCreateView WhoAmIView
)
router = DefaultRouter()
router.register(r'predictions', PredictionViewSet, basename='predictions')
router.register(r'saved-points', SavedPointViewset, basename='saved-points')
urlpatterns = [ urlpatterns = [
path('predictions', PredictionCreateView.as_view(), name='create_prediction'), path("csrf/", get_csrf, name='api-csrf'),
path('predictions/list/', PredictionListView.as_view(), name='get_predictions'),
path('token', obtain_auth_token, name = 'get_token'), path('token', obtain_auth_token, name = 'get_token'),
path("history", PredictionHistoryListView.as_view(), name='view_history_list'), path("login/", login_view, name='api-login'),
path("history/<uuid:pk>/", PredictionHistoryDetailView.as_view(), name='view_history_detail'), path("logout/", logout_view, name='api-logout'),
path("history/<uuid:pk>/delete/", PredictionHistoryDeleteView.as_view(), name='delete_history'), path("session/", SessionView.as_view(), name='api-session'),
path("whoami/", WhoAmIView.as_view(), name='api-whoami'),
path("<uuid:pk>/telemetry/", TelemetryListCreateView.as_view(), name="create_telemetry"), path("<uuid:pk>/telemetry/", TelemetryListCreateView.as_view(), name="create_telemetry"),
path('saved-points/', SavedPointViewset.as_view({'get': 'list', 'post': 'create', 'put': 'update', 'delete': 'destroy'}), name='saved_points'),
path('csrf/', get_csrf, name='api-csrf'),
path('login/', login_view, name='api-login'),
path('logout/', logout_view, name='api-logout'),
path('session/', SessionView.as_view(), name='api-session'), # new
path('whoami/', WhoAmIView.as_view(), name='api-whoami'), # new
] ]
urlpatterns += router.urls

View file

@ -1,34 +1,34 @@
import requests
import time
import json
from rest_framework import status, generics, permissions from rest_framework import status, generics, permissions
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet, ViewSet
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.decorators import api_view, permission_classes, authentication_classes, action
from django.utils import timezone from django.utils import timezone
from .models import Prediction, User, Satellite, SavedPoint, SavedRateProfile, PreditctionTemplate
from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer, SavedPointSerializer, SavedRateProfileSerializer, PreditctionTemplateSerializer
from rest_framework.permissions import IsAuthenticated
import requests
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from rest_framework.permissions import AllowAny
from .services.tawhiri import TawhiriClient
from django.contrib.auth import get_user_model
from .models import Satellite, TelemetryPacket
from .serializers import TelemetryPacketSerializer
from .permissions import ReadOnlyOrAuthenticated, IsOwner
import time
from django.http import JsonResponse from django.http import JsonResponse
from rest_framework.authentication import SessionAuthentication, BasicAuthentication from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.auth import authenticate, login, logout
import json
from django.middleware.csrf import get_token from django.middleware.csrf import get_token
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from drf_spectacular.utils import extend_schema
from django.utils.dateparse import parse_datetime from django.utils.dateparse import parse_datetime
from .models import Prediction, User, Satellite, SavedPoint, SavedRateProfile, PreditctionTemplate, TelemetryPacket
from .serializers import PredictionSerializer, TelemetryPacketSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer, SavedPointSerializer, SavedRateProfileSerializer, PreditctionTemplateSerializer
from .services.tawhiri import TawhiriClient
from drf_spectacular.utils import extend_schema
from .permissions import ReadOnlyOrAuthenticated, IsOwner
User = get_user_model() User = get_user_model()
def get_prediction_from_tawhiri(params): def get_prediction_from_tawhiri(params):
base_url = "https://fly.stratonautica.ru/api/v2" base_url = "https://fly.stratonautica.ru/api/v2"
response = requests.get(base_url, params=params) response = requests.get(base_url, params=params)
@ -39,14 +39,14 @@ def get_prediction_from_tawhiri(params):
class PredictionCreateView(APIView): class PredictionViewSet(ViewSet):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def post(self, request):
print("DEBUG: request.user =", request.user)
print("DEBUG: request.user.id =", request.user.id)
def create(self, request):
serializer = PredictionRequestSerializer(data=request.data) serializer = PredictionRequestSerializer(data=request.data)
if not serializer.is_valid(): if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@ -54,11 +54,12 @@ class PredictionCreateView(APIView):
try: try:
prediction_result = TawhiriClient.get_prediction(validated_data) prediction_result = TawhiriClient.get_prediction(validated_data)
except requests.RequestException as e: except requests.RequestException as e:
print("Tawhiri error:", str(e), e.response.text if e.response else "no response")
return Response({"error": f"Tawhiri error: {str(e)}"}, status=status.HTTP_502_BAD_GATEWAY) return Response({"error": f"Tawhiri error: {str(e)}"}, status=status.HTTP_502_BAD_GATEWAY)
prediction = Prediction.objects.create(result=prediction_result, user=request.user, request=request.data) prediction = Prediction.objects.create(result=prediction_result, user=request.user, request=request.data)
return Response({ return Response({
"id": prediction.id, "id": prediction.id,
"created_at": prediction.created_at, "created_at": prediction.created_at,
@ -66,66 +67,60 @@ class PredictionCreateView(APIView):
}, status=status.HTTP_201_CREATED) }, status=status.HTTP_201_CREATED)
class PredictionListView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request): @action(detail=False, methods=['get'])
def list_user(self, request):
user = request.user user = request.user
satellite_id = request.query_params.get('satellite_id') satellite_id = request.query_params.get('satellite_id')
created_from = request.query_params.get('created_from') created_from = request.query_params.get('created_from')
created_till = request.query_params.get('created_till') created_till = request.query_params.get('created_till')
# Проверка доступа к спутнику
if satellite_id and not user.satellites.filter(id=satellite_id).exists():
return Response({'detail': 'Access to this satellite is forbidden.'}, status=403)
filters = { filters = {
'id__in': Prediction.objects.filter(user=user).values_list('prediction_id', flat=True), 'user': user,
'deleted_at__isnull': True 'deleted_at__isnull': True
} }
print(filters)
print(Prediction.objects.filter(**filters))
if created_from: if created_from:
filters['created_at__gte'] = parse_datetime(created_from) filters['created_at__gte'] = parse_datetime(created_from)
if created_till: if created_till:
filters['created_at__lte'] = parse_datetime(created_till) filters['created_at__lte'] = parse_datetime(created_till)
if satellite_id: if satellite_id:
if not user.satellites.filter(id=satellite_id).exists():
return Response({'detail': 'Access denied'}, status=403)
filters['satellite_id'] = satellite_id filters['satellite_id'] = satellite_id
predictions = Prediction.objects.filter(**filters) queryset = Prediction.objects.filter(**filters)
return Response(PredictionSerializer(predictions, many=True).data) return Response(PredictionSerializer(queryset, many=True).data)
class PredictionHistoryListView(generics.ListAPIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = PredictionListSerializer
def get_queryset(self):
return Prediction.objects.filter(
user=self.request.user,
)
class PredictionHistoryDetailView(generics.RetrieveAPIView): @action(detail=False, methods=["get"])
permission_classes = [permissions.IsAuthenticated] def history(self, request):
serializer_class = PredictionDetailSerializer queryset = Prediction.objects.filter(user=request.user)
return Response(PredictionListSerializer(queryset, many=True).data)
def get_queryset(self):
return Prediction.objects.filter(
user=self.request.user,
)
class PredictionHistoryDeleteView(generics.DestroyAPIView): @action(detail=True, methods=["get"])
permission_classes = [permissions.IsAuthenticated] def detail(self, request, pk=None):
prediction = Prediction.objects.filter(user=request.user, pk=pk).first()
if not prediction:
return Response({'detail': 'Not found'}, status=404)
return Response(PredictionDetailSerializer(prediction).data)
@action(detail=True, methods=["delete"])
def delete(self, request, pk=None):
prediction = Prediction.objects.filter(user=request.user, pk=pk).first()
if not prediction:
return Response({'detail': 'Not found'}, status=404)
prediction.delete()
return Response(status=204)
def get_queryset(self):
return Prediction.objects.filter(
user=self.request.user,
)
class TelemetryListCreateView(generics.ListCreateAPIView): class TelemetryListCreateView(generics.ListCreateAPIView):
@ -164,6 +159,7 @@ class TelemetryListCreateView(generics.ListCreateAPIView):
return Response(serializer.errors, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_201_CREATED)
class SessionView(APIView): class SessionView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication] authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -173,6 +169,7 @@ class SessionView(APIView):
return JsonResponse({'isAuthenticated': True}) return JsonResponse({'isAuthenticated': True})
class WhoAmIView(APIView): class WhoAmIView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication] authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@ -182,6 +179,7 @@ class WhoAmIView(APIView):
return JsonResponse({'username': request.user.username}) return JsonResponse({'username': request.user.username})
@extend_schema(methods=["GET"], description="Get CSRF token") @extend_schema(methods=["GET"], description="Get CSRF token")
@api_view(["GET"]) @api_view(["GET"])
@permission_classes([AllowAny]) @permission_classes([AllowAny])
@ -191,6 +189,7 @@ def get_csrf(request):
return response return response
@extend_schema(methods=["POST"], description="Login user") @extend_schema(methods=["POST"], description="Login user")
@csrf_exempt @csrf_exempt
@api_view(["POST"]) @api_view(["POST"])
@ -212,6 +211,7 @@ def login_view(request):
return JsonResponse({'detail': 'Successfully logged in.'}) return JsonResponse({'detail': 'Successfully logged in.'})
@extend_schema(methods=["POST"], description="Logout user") @extend_schema(methods=["POST"], description="Logout user")
@api_view(["POST"]) @api_view(["POST"])
@permission_classes([AllowAny]) @permission_classes([AllowAny])
@ -223,6 +223,7 @@ def logout_view(request):
return JsonResponse({'detail': 'Successfully logged out.'}) return JsonResponse({'detail': 'Successfully logged out.'})
class SavedPointViewset(ModelViewSet): class SavedPointViewset(ModelViewSet):
authentication_classes = [SessionAuthentication, BasicAuthentication] authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsOwner] permission_classes = [IsOwner]

View file

@ -1,4 +1,3 @@
version: '3.8'
services: services:
db: db: