Can I use a keyword argument from another app to connect the URLs of two different aps together?

Viewed 25

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!

0 Answers
Related