Add models for user data

This commit is contained in:
ThePetrovich 2025-06-25 19:19:59 +08:00
parent b49adc60f5
commit 8f61eb0834
6 changed files with 212 additions and 32 deletions

2
.gitignore vendored
View file

@ -1,6 +1,8 @@
# Python # Python
__pycache__/ __pycache__/
**/__pycache__/**
*.py[cod] *.py[cod]
*pyc
*.pyo *.pyo
*.pyd *.pyd
*.so *.so

View file

@ -1,9 +1,8 @@
from django.contrib import admin from django.contrib import admin
from .models import User, Prediction, UserPrediction, Satellite, TelemetryPacket from .models import User, Prediction, Satellite, TelemetryPacket
admin.site.register(User) admin.site.register(User)
admin.site.register(Prediction) admin.site.register(Prediction)
admin.site.register(UserPrediction)
admin.site.register(Satellite) admin.site.register(Satellite)
admin.site.register(TelemetryPacket) admin.site.register(TelemetryPacket)

View file

@ -0,0 +1,136 @@
# Generated by Django 4.2.23 on 2025-06-25 11:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='PreditctionTemplate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('template_data', models.JSONField(blank=True, default=dict)),
('is_default', models.BooleanField(default=False)),
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'name')},
},
),
migrations.CreateModel(
name='SavedPoint',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('lat', models.FloatField(default=0.0)),
('lon', models.FloatField(default=0.0)),
('alt', models.FloatField(default=0.0)),
('is_default', models.BooleanField(default=False)),
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'name')},
},
),
migrations.CreateModel(
name='SavedRateProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('rate_profile_data', models.JSONField(blank=True, default=dict)),
('is_default', models.BooleanField(default=False)),
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'name')},
},
),
migrations.RemoveField(
model_name='prediction',
name='deleted_at',
),
migrations.AddField(
model_name='prediction',
name='request',
field=models.JSONField(default=dict),
),
migrations.AddField(
model_name='prediction',
name='user',
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='predictions', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='satellite',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='satellite',
name='image',
field=models.ImageField(blank=True, null=True, upload_to='satellite_images/'),
),
migrations.AddField(
model_name='satellite',
name='metadata',
field=models.JSONField(blank=True, default=dict),
),
migrations.AddField(
model_name='satellite',
name='user',
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='telemetrypacket',
name='raw_data',
field=models.JSONField(blank=True, default=dict),
),
migrations.AddField(
model_name='telemetrypacket',
name='user',
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='prediction',
name='result',
field=models.JSONField(default=dict),
),
migrations.AlterField(
model_name='telemetrypacket',
name='alt',
field=models.FloatField(default=0.0),
),
migrations.AlterField(
model_name='telemetrypacket',
name='lat',
field=models.FloatField(default=0.0),
),
migrations.AlterField(
model_name='telemetrypacket',
name='lon',
field=models.FloatField(default=0.0),
),
migrations.AlterField(
model_name='telemetrypacket',
name='payload',
field=models.JSONField(blank=True, default=dict),
),
migrations.DeleteModel(
name='UserPrediction',
),
]

View file

@ -1,36 +1,87 @@
import uuid import uuid
from django.db import models from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser, AnonymousUser
class User(AbstractUser): class User(AbstractUser):
satellites = models.ManyToManyField("Satellite", related_name="users") satellites = models.ManyToManyField("Satellite", related_name="users")
class Prediction(models.Model): class Prediction(models.Model):
satellite = models.ForeignKey('Satellite', on_delete=models.CASCADE, related_name='predictions', null=True) user = models.ForeignKey(get_user_model(
), on_delete=models.CASCADE, default=0, related_name='predictions')
satellite = models.ForeignKey(
'Satellite', on_delete=models.CASCADE, related_name='predictions', null=True)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
result = models.JSONField() request = models.JSONField(default=dict)
deleted_at = models.DateTimeField(null=True, blank=True) result = models.JSONField(default=dict)
class UserPrediction(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
prediction = models.ForeignKey("Prediction", on_delete=models.CASCADE)
created_at = models.DateTimeField()
class Satellite(models.Model): class Satellite(models.Model):
user = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, default=0)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
metadata = models.JSONField(blank=True, default=dict)
image = models.ImageField(
upload_to='satellite_images/', blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
class TelemetryPacket(models.Model): class TelemetryPacket(models.Model):
user = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, default=0)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
satellite = models.ForeignKey(Satellite, on_delete=models.CASCADE, related_name="telemetry") satellite = models.ForeignKey(
Satellite, on_delete=models.CASCADE, related_name="telemetry")
timestamp = models.BigIntegerField() # unix time timestamp = models.BigIntegerField() # unix time
lat = models.FloatField() lat = models.FloatField(default=0.0)
lon = models.FloatField() lon = models.FloatField(default=0.0)
alt = models.FloatField() alt = models.FloatField(default=0.0)
payload = models.JSONField(null=True, blank=True) payload = models.JSONField(blank=True, default=dict)
raw_data = models.JSONField(blank=True, default=dict)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
class PreditctionTemplate(models.Model):
user = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, default=0)
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
template_data = models.JSONField(blank=True, default=dict)
is_default = models.BooleanField(default=False)
class Meta:
unique_together = ('user', 'name')
class SavedPoint(models.Model):
user = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, default=0)
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
lat = models.FloatField(default=0.0)
lon = models.FloatField(default=0.0)
alt = models.FloatField(default=0.0)
is_default = models.BooleanField(default=False)
class Meta:
unique_together = ('user', 'name')
class SavedRateProfile(models.Model):
user = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, default=0)
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
rate_profile_data = models.JSONField(blank=True, default=dict)
is_default = models.BooleanField(default=False)
class Meta:
unique_together = ('user', 'name')

View file

@ -2,7 +2,7 @@ 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 django.utils import timezone from django.utils import timezone
from .models import Prediction, User, UserPrediction from .models import Prediction, User
from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
import requests import requests
@ -57,8 +57,7 @@ class PredictionCreateView(APIView):
print("Tawhiri error:", str(e), e.response.text if e.response else "no response") 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) prediction = Prediction.objects.create(result=prediction_result, user=request.user, request=validated_data)
UserPrediction.objects.create(user=request.user, prediction=prediction, created_at=timezone.now())
return Response({ return Response({
"id": prediction.id, "id": prediction.id,
"created_at": prediction.created_at, "created_at": prediction.created_at,
@ -80,7 +79,7 @@ class PredictionListView(APIView):
return Response({'detail': 'Access to this satellite is forbidden.'}, status=403) return Response({'detail': 'Access to this satellite is forbidden.'}, status=403)
filters = { filters = {
'id__in': UserPrediction.objects.filter(user=user).values_list('prediction_id', flat=True), 'id__in': Prediction.objects.filter(user=user).values_list('prediction_id', flat=True),
'deleted_at__isnull': True 'deleted_at__isnull': True
} }
print(filters) print(filters)
@ -103,8 +102,7 @@ class PredictionHistoryListView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
return Prediction.objects.filter( return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True), user=self.request.user,
deleted_at__isnull=True
) )
@ -115,8 +113,7 @@ class PredictionHistoryDetailView(generics.RetrieveAPIView):
def get_queryset(self): def get_queryset(self):
return Prediction.objects.filter( return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True), user=self.request.user,
deleted_at__isnull=True
) )
@ -126,15 +123,9 @@ class PredictionHistoryDeleteView(generics.DestroyAPIView):
def get_queryset(self): def get_queryset(self):
return Prediction.objects.filter( return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True), user=self.request.user,
deleted_at__isnull=True
) )
def perform_destroy(self, instance):
instance.deleted_at = timezone.now()
instance.save()
class TelemetryListCreateView(generics.ListCreateAPIView): class TelemetryListCreateView(generics.ListCreateAPIView):
serializer_class = TelemetryPacketSerializer serializer_class = TelemetryPacketSerializer

View file

@ -5,4 +5,5 @@ psycopg2-binary
drf-spectacular drf-spectacular
requests requests
django-cors-headers django-cors-headers
Pillow