barebone app with django and react, sse, jwt token, comport reader, test comport writer, requires com0com, users with groups, sample table vehicles, tokens for access and refresh

This commit is contained in:
2026-01-17 13:03:21 +02:00
commit 7f04566242
81 changed files with 22551 additions and 0 deletions
View File
+3
View File
@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class VehiclesConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "vehicles"
@@ -0,0 +1,52 @@
# Generated by Django 4.2.8 on 2026-01-13 16:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Vehicle",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("vehicle_number", models.CharField(max_length=15, unique=True)),
],
),
migrations.CreateModel(
name="VehicleExtra",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("data", models.JSONField(default=dict)),
(
"vehicle",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="extra",
to="vehicles.vehicle",
),
),
],
),
]
+14
View File
@@ -0,0 +1,14 @@
from django.db import models
# Create your models here.
class Vehicle(models.Model):
vehicle_number = models.CharField(max_length=15, unique=True)
def __str__(self):
return f"{self.vehicle_number}"
class VehicleExtra(models.Model):
vehicle = models.OneToOneField(
Vehicle, on_delete=models.CASCADE, related_name="extra"
)
data = models.JSONField(default=dict)
+7
View File
@@ -0,0 +1,7 @@
from rest_framework import serializers
from .models import Vehicle
class VehicleSerializer(serializers.ModelSerializer):
class Meta:
model = Vehicle
fields = ['id', 'vehicle_number']
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+10
View File
@@ -0,0 +1,10 @@
from django.urls import path
from vehicles.views import vehiclesView, VehicleListCreateAPIView, VehicleRetrieveUpdateDestroyAPIView, get_vehicles
urlpatterns = [
path("", vehiclesView.as_view(), name='list_vehicles'),
# API endpoints
path("api/", VehicleListCreateAPIView.as_view(), name='vehicles-list-create'),
path("api/<int:pk>/", VehicleRetrieveUpdateDestroyAPIView.as_view(), name='vehicles-detail'),
path("api/list/", get_vehicles, name='get-vehicles'),
]
+70
View File
@@ -0,0 +1,70 @@
from django.shortcuts import render
from django.shortcuts import render
from django.views.generic.list import ListView
from rest_framework import generics, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import Vehicle
from .serializers import VehicleSerializer
from scalesapp.sse import broadcast_update
# Create your views here.
class CountriesView(ListView):
pass
# API Views
class VehicleListCreateAPIView(generics.ListCreateAPIView):
queryset =Vehicle.objects.all()
serializer_class = VehicleSerializer
permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs):
"""Override create to broadcast SSE message"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
# Broadcast SSE update
broadcast_update('vehicle', 'created', serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
class VehicleRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Vehicle.objects.all()
serializer_class = VehicleSerializer
permission_classes = [IsAuthenticated]
def update(self, request, *args, **kwargs):
"""Override update to broadcast SSE message"""
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
# Broadcast SSE update
broadcast_update('vehicle', 'updated', serializer.data)
return Response(serializer.data)
def destroy(self, request, *args, **kwargs):
"""Override destroy to broadcast SSE message"""
instance = self.get_object()
country_data = CountrySerializer(instance).data
self.perform_destroy(instance)
# Broadcast SSE update
broadcast_update('vehicle', 'deleted', country_data)
return Response(status=status.HTTP_204_NO_CONTENT)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_vehicles(request):
"""API endpoint for getting countries list"""
vehicles = Vehicle.objects.all().order_by('id')
serializer = VehicleSerializer(vehicles, many=True)
return Response(serializer.data)