I'm currently developing an application using the Django REST Framework and Vue in which people can monitor a device's signal outputs.
For some context, I created a custom user model with a unique UUID4 user ID that would be assigned to each user. This model is in a Django app that I called accounts. Similarly, I have the user's data recording sessions and associated data in separate models in an app that I call studio.
My problem is this: I realized I would like to associate the data collected to the user's account and whatever session they wish to tie this data to. However, since these models are in different Django apps, I am getting the error
get() got an unexpected keyword argument 'user_id' when I try to tie the URLs of the account and studio apps together. Relevant code snippets are below:
models.py (in studio)
from django.db import models
class Session(models.Model):
user_id = models.ForeignKey(
'accounts.CustomUser', on_delete=models.CASCADE)
session_id = models.CharField(max_length=100, unique=True, blank=False)
def get_associated_user_id(self):
return (f'{self.user_id}')
def __str__(self):
return (f"Session ID: {self.session_id}")
class LaserData(models.Model):
user_id = models.ForeignKey(
'accounts.CustomUser', on_delete=models.CASCADE)
session_id = models.ForeignKey('Session', on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
laser_current = models.DecimalField(max_digits=8, decimal_places=3)
laser_temperature = models.DecimalField(max_digits=8, decimal_places=3)
laser_temperature_set = models.DecimalField(max_digits=8, decimal_places=3)
tec_voltage_positive = models.DecimalField(max_digits=8, decimal_places=3)
tec_voltage_negative = models.DecimalField(max_digits=8, decimal_places=3)
tec_voltage_differential = models.DecimalField(
max_digits=8, decimal_places=3)
ambient_temperature = models.DecimalField(max_digits=8, decimal_places=3)
class Meta:
ordering = ('timestamp',)
def get_associated_user_id(self):
return (f'{self.user_id}')
def get_associated_session_id(self):
return self.session_id
def __str__(self):
return (f"MicroModule data recorded at {self.timestamp}.")
views.py (in studio)
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import render
from django.http.response import Http404
from .models import Session, LaserData
from .serializers import SessionSerializer, LaserDataSerializer
class SessionListView(APIView):
def get(self, request, u_id, format=None):
session = Session.objects.get(user_id=u_id)[0:9]
serializer = SessionSerializer(session, many=True)
return Response(serializer.data)
def post(self, request):
serializer = SessionSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
class SessionDetailView(APIView):
def get_session(self, u_id, s_id):
try:
return Session.objects.filter(user_id=u_id).get(session_id=s_id)
except Session.DoesNotExist:
raise Http404
def get(self, request, user_id, session_id, format=None):
session = self.get_session(user_id, session_id)
serializer = SessionSerializer(session)
return Response(serializer.data)
class LaserDataListView(APIView):
def get(self, request, u_id, s_id, format=None):
laser_data = LaserData.objects.get(
user_id=u_id, session_id=s_id)[0:9]
serializer = LaserDataSerializer(laser_data, many=True)
return Response(serializer.data)
def post(self, request):
serializer = LaserDataSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
class LaserDatumDetailView(APIView):
def get_datum(self, u_id, s_id, time):
try:
return LaserData.objects.get(
user_id=u_id,
session_id=s_id,
timestamp=time
)
except LaserData.DoesNotExist:
raise Http404
def get(self, request, user_id, session_id, timestamp, format=None):
laser_datum = self.get_datum(user_id, session_id, timestamp)
serializer = LaserDataSerializer(laser_datum)
return Response(serializer.data)
urls.py (in studio)
from django.urls import path, include
from . import views
urlpatterns = [
path(r'sessions/', views.SessionListView.as_view()),
path(r'sessions/<str:session_id>/',
views.SessionDetailView.as_view()),
path(r'sessions/<str:session_id>/laser-data/',
views.LaserDataListView.as_view()),
path(r'sessions/<str:session_id>/laser-data/<str:timestamp>/',
views.LaserDatumDetailView.as_view()),
]
models.py(in accounts)
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager
)
import uuid
class CustomUserManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError('User must have an email address.')
custom_user = self.model(
username=username,
email=self.normalize_email(email),
)
custom_user.set_password(password)
custom_user.save(using=self._db)
return custom_user
def create_staffuser(self, email, username, password):
custom_staffuser = self.create_user(
email,
username,
password=password,
)
custom_staffuser.staff = True
custom_staffuser.save(using=self._db)
return custom_staffuser
def create_superuser(self, email, username, password):
custom_superuser = self.create_user(
email,
username,
password=password,
)
custom_superuser.staff = True
custom_superuser.admin = True
custom_superuser.save(using=self._db)
return custom_superuser
class CustomUser(AbstractBaseUser):
# Required Fields
user_id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False
)
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
username = models.CharField(
max_length=255,
unique=True,
blank=False
)
# Optional Fields
first_name = models.CharField(
max_length=255,
blank=True,
default=''
)
last_name = models.CharField(
max_length=255,
blank=True,
default=''
)
company_or_organization = models.CharField(
max_length=255,
blank=True,
default=''
)
purpose = models.TextField(
max_length=1000,
blank=True,
default=''
)
mm_serial_number = models.CharField(
max_length=255,
blank=True,
default=''
)
# Status
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
# Staff Permissions
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
class Meta:
ordering = ['date_joined']
objects = CustomUserManager()
def get_first_name(self):
return self.first_name
def get_last_name(self):
return self.last_name
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, application_label):
return True
def __str__(self):
return (f'{self.user_id}')
@property
def is_staff(self):
return self.staff
@property
def is_admin(self):
return self.admin
views.py (in accounts)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions, status
from django.http.response import Http404
from django.contrib.auth import get_user_model
from .serializers import CustomUserSerializer
import uuid
CustomUser = get_user_model()
class CustomUserListView(APIView):
def get(self, request, format=None):
custom_users = CustomUser.objects.all()
serializer = CustomUserSerializer(custom_users, many=True)
return Response(serializer.data)
def post(self, request):
serializer = CustomUserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CustomUserDetailView(APIView):
def get_user(self, id):
try:
return CustomUser.objects.get(user_id=id)
except CustomUser.DoesNotExist:
raise Http404
def get(self, request, user_id, format=None):
custom_user = self.get_user(user_id)
serializer = CustomUserSerializer(custom_user)
return Response(serializer.data)
def put(self, request, user_id):
custom_user = self.get_user(user_id)
serializer = CustomUserSerializer(custom_user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py (in accounts)
from django.urls import path, include
from . import views
urlpatterns = [
path(r'accounts/', views.CustomUserListView.as_view()),
path(r'accounts/<uuid:user_id>/',
views.CustomUserDetailView.as_view(), name='my-account'),
path(r'accounts/<uuid:user_id>/', include('studio.urls')),
]
This is my first time writing a web application of any sort so please don't flame me too much. I would appreciate any help on my main problem as well as any pointers/tips for best practice in web application development.
Thank you all in advance!