Kosmylo
Kosmylo

Reputation: 428

Cannot properly save to a db with OneToOne relationship

The flow of what I want to do is the following:

I have two tables, namely Event and Result. The Event table is connected with ForeignKey with a user and the Result table is connected with OneToOne relationship with Event. In my views.py I have one POST and one GET. In POST, I take some data and save it in the table Event. In GET, I solve an optimization problem and I want to save the solution into Result.

The models.py is as follows:

from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.auth import get_user_model

CustomUser = get_user_model()

class Event(models.Model):
    
    user_id_event = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True)
    dr_notice_period = models.IntegerField(blank=True, null=True)
    dr_duration = models.IntegerField(blank=True, null=True)
    dr_request = models.FloatField(blank=True, null=True)

class Result(models.Model):

    event_id_result = models.OneToOneField(Event, on_delete=models.CASCADE, null=True)
    HVAC_flex = ArrayField(models.FloatField(blank=True, null=True))
    DHW_flex = ArrayField(models.FloatField(blank=True, null=True))
    lights_flex = ArrayField(models.FloatField(blank=True, null=True))

The serializers.py is as follows:

from rest_framework import serializers
from vpp_optimization.models import Event, Result

class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = Event
        fields = ('__all__')

class ResultSerializer(serializers.ModelSerializer):
    HVAC_flex = serializers.ListField(child=serializers.FloatField())
    DHW_flex = serializers.ListField(child=serializers.FloatField())
    lights_flex = serializers.ListField(child=serializers.FloatField())

    class Meta:
        model = Result
        fields = ('__all__')

The views.py is as follows:

from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework import status

from vpp_optimization.importer import DR_event_import_data
from vpp_optimization.utils import optimization_solution, convert_dict_for_serializer
from vpp_optimization.serializers import EventSerializer, ResultSerializer
from vpp_optimization.models import Event, Result

@api_view(['POST'])
@permission_classes([IsAuthenticated,])
def event(request):
    serializer = EventSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save(user_id_event=request.user)
        return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
    else:
        return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
def optimization(request):
    last_event = Event.objects.last()

    if not last_event:
        return Response({"res": "Object Event does not exists"}, status=status.HTTP_400_BAD_REQUEST)

    serializer = EventSerializer(last_event)
    
    response_dict = {}
    DR_event_data = DR_event_import_data(serializer.data)
    response_dict = optimization_solution(DR_event_data)
    response_dict_final = convert_dict_for_serializer(response_dict)

    serializer_result = ResultSerializer(data=response_dict_final)

    if serializer_result.is_valid():
        serializer_result.save(event_id_result=last_event.id)
    
    return Response(serializer_result.data, status=status.HTTP_200_OK)

However, I am getting the following error:

ValueError: Cannot assign "2": "Result.event_id_result" must be a "Event" instance.

The error is due to the way that I am trying to save with the OneToOne relationship, namely in this line of the views.py:

event_id_result=last_event.id

Apparently, this is not the correct way to connect the two databases. Does anyone can help me find the correct way?

Upvotes: 0

Views: 34

Answers (1)

Kovy Jacob
Kovy Jacob

Reputation: 977

Change:

event_id_result=last_event.id

To:

event_id_result=last_event

Upvotes: 1

Related Questions