__str__ returned non-string (type int) returned from Model

Below is the Model.py

from django.db import models

class workflow_details(models.Model):
    workflow_name = models.CharField(max_length=20,)
    workflow_id = models.IntegerField(primary_key=True)
    workflow_status=models.BooleanField()
    def __str__(self):
        return self.workflow_id
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Details'

class workflow_steps(models.Model):
    workflow_id=models.ForeignKey('workflows.workflow_details',to_field='workflow_id',on_delete=models.CASCADE)
    step_id=models.CharField(max_length=20,primary_key=True)
    step_name=models.CharField(max_length=20)
    is_start=models.BooleanField()
    is_end=models.BooleanField()
    previous_step_id=models.CharField(max_length=20)
    next_step_id=models.CharField(max_length=20)
    step_function=models.CharField(max_length=255)

    def __str__(self):
        return self.step_id 
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Steps'

class workflow_execution(models.Model):
    workflow_id=models.ForeignKey('workflows.workflow_details',to_field='workflow_id',on_delete=models.PROTECT)
    execution_id=models.CharField(max_length=30,primary_key=True)
    step_id=models.CharField(max_length=20)
    step_name=models.CharField(max_length=20)
    is_start=models.CharField(max_length=5)
    is_end=models.CharField(max_length=5)
    previous_step_id=models.CharField(max_length=20,default='')
    next_step_id=models.CharField(max_length=20,default='')
    start_time=models.CharField(max_length=20,default='')
    end_time=models.CharField(max_length=20,default='')
    execution_time=models.CharField(max_length=20,default='')
    success=models.CharField(max_length=5,default='')
    failure=models.CharField(max_length=5,default='')
    current_status=models.CharField(max_length=10,default='')


    def __str__(self):
        return str(self.execution_id)
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Execution'

below is the snippet of the code i am using to insert data in it

def register_run(self,workflow_id,execution_id):
        wd = workflow_details.objects.filter(workflow_id=workflow_id)
        ws = workflow_steps.objects.filter(workflow_id=workflow_id).values()
        sorted_data = sorted(ws, key=lambda x: x['step_id'])
        for data in sorted_data:
            step_id=data.get('step_id')
            step_name=data.get('step_name')
            is_start=data.get('is_start')
            is_end=data.get('is_end')
            previous_step_id=data.get('previous_step_id')
            next_step_id=data.get('next_step_id')
            we=workflow_execution(workflow_id=wd,execution_id=execution_id,step_id=step_id,step_name=step_name,is_start=is_start,is_end=is_end,previous_step_id=previous_step_id,next_step_id=next_step_id,current_status='idle')
            we.save()
        return True

I am constantly getting the below error
__str__ returned non-string (type int)

Even though the return type for the class is set as string

Below is the image for reference

Please help me point out the exact issue

Your __str__ method here is going to return the workflow_id, which is an integer. It is not a string.

You have the same problem with workflow_steps as well.

Note:

A class does not have a return type.

Side note: I would strongly encourage you to adopt the Python / Django naming conventions regarding your class names.

I have changed all the return types for def __str__(self) and have type casted it to str, but now i am getting a different error

Exception has occurred: ValueError
Cannot assign "<QuerySet [<workflow_details: 1234>]>": "workflow_execution.workflow_id" must be a "workflow_details" instance.
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/workflow_engine.py", line 113, in register_run
    we=workflow_execution(workflow_id=wd,execution_id=execution_id,step_id=step_id,step_name=step_name,is_start=is_start,is_end=is_end,previous_step_id=previous_step_id,next_step_id=next_step_id,current_status='idle')
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/workflow_engine.py", line 126, in run
    self.register_run(workflow_id,execution_id)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/middleware.py", line 25, in runwork_flow
    r.run(workflow_id)
ValueError: Cannot assign "<QuerySet [<workflow_details: 1234>]>": "workflow_execution.workflow_id" must be a "workflow_details" instance.

Earlier when the return type was not typecasted to str for workflow_details and workflow_steps i was able to insert data to the database without any issues, below are the snippets for the same

This is for inserting data to steps

wd=workflow_details.objects.get(workflow_id=id)
items = list(steps.items())
lenk=len(items)
step_id=((int(id)*10000)+1)
prev_step_id=0
next_step_id=0
for val,item in enumerate(items):
    if val==0:
        name,function=item
        nstpid=step_id+1
        ws=workflow_steps(workflow_id=wd,step_id=step_id,step_name=name,step_function=function,is_start=True,is_end=False,previous_step_id="None",next_step_id=nstpid)
        ws.save()
        step_id+=1

This is for entering the data to workflow

wd=workflow_details(workflow_name=flow.get('workflow_name'),workflow_id=flow.get('workflow_id'),workflow_status=flow.get('workflow_status'))
wd.save()

Please do not post images of code or error messages here. Copy/paste the text into the body of your post, surrounded by lines of three backticks - `, just like you’re doing with your other code fragments.

I have edited the last post, can you please let me know what caused the error, as i have type casted the return types to str

Side note:

to avoid more confusion, these fields should be named workflow and not workflow_id.

When working with the Django ORM, those fields are references to the objects of the related type. The _id version of the field name is an internal definition to Django for the pk field itself.

This means that anytime you will try to use the workflow attribute, you are referring to the object, and anytime you reference workflow_id you will be referring to the integer key.

Now, regarding this error:

You have:

The error message is quite explicit. You’re trying to set this workflow_id attribute to wd, but wd is not an instance of workflow_details - it’s a queryset.

I got this error and this happens when i explicitly type cast the return, but still i haven’t understood what is causing the first error as the return for workflow execution is set to str only.

class workflow_execution(models.Model):
    workflow_id=models.ForeignKey('workflows.workflow_details',to_field='workflow_id',on_delete=models.PROTECT)
    execution_id=models.CharField(max_length=30,primary_key=True)
    step_id=models.CharField(max_length=20)
    step_name=models.CharField(max_length=20)
    is_start=models.CharField(max_length=5)
    is_end=models.CharField(max_length=5)
    previous_step_id=models.CharField(max_length=20,default='')
    next_step_id=models.CharField(max_length=20,default='')
    start_time=models.CharField(max_length=20,default='')
    end_time=models.CharField(max_length=20,default='')
    execution_time=models.CharField(max_length=20,default='')
    success=models.CharField(max_length=5,default='')
    failure=models.CharField(max_length=5,default='')
    current_status=models.CharField(max_length=10,default='')


    def __str__(self):
        return str(self.execution_id)
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Execution'

What error are you referring to? If it’s this last one (ValueError: Cannot assign ...), then it has nothing to do with your __str__ function. It has to do with the variables being used in the constructor as I identified above.

If you’re referring to a different error, please post the complete traceback.

This is the error i am referring to

Exception in thread run flow:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/middleware.py", line 25, in runwork_flow
    r.run(workflow_id)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/workflow_engine.py", line 128, in run
    self.register_run(workflow_id,execution_id,wd,ws)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/Kappa/workflows/workflow_engine.py", line 115, in register_run
    workflow_execution.objects.create(workflow_id=wd,execution_id=execution_id,step_id=step_id,step_name=step_name,is_start=is_start,is_end=is_end,previous_step_id=previous_step_id,next_step_id=next_step_id,current_status='idle')
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/query.py", line 656, in create
    obj = self.model(**kwargs)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/base.py", line 543, in __init__
    _setattr(self, field.name, rel_obj)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/fields/related_descriptors.py", line 267, in __set__
    'Cannot assign "%r": "%s.%s" must be a "%s" instance.'
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/query.py", line 377, in __repr__
    return "<%s %r>" % (self.__class__.__name__, data)
  File "/Users/arijitdas/Desktop/My Folder/Django_vscode/virtualenv/lib/python3.10/site-packages/django/db/models/base.py", line 588, in __repr__
    return "<%s: %s>" % (self.__class__.__name__, self)
TypeError: __str__ returned non-string (type int)

This error got generated from this piece of the code when trying to execute data to workflow execution.

def register_run(self,workflow_id,execution_id,wd,ws):
        #wd = workflow_details.objects.filter(workflow_id=workflow_id)
        #ws = workflow_steps.objects.filter(workflow_id=workflow_id).values()
        wd=wd
        ws=ws
        sorted_data = sorted(ws, key=lambda x: x['step_id'])
        for data in sorted_data:
            step_id=data.get('step_id')
            step_name=data.get('step_name')
            is_start=data.get('is_start')
            is_end=data.get('is_end')
            previous_step_id=data.get('previous_step_id')
            next_step_id=data.get('next_step_id')
            workflow_execution.objects.create(workflow_id=wd,execution_id=execution_id,step_id=step_id,step_name=step_name,is_start=is_start,is_end=is_end,previous_step_id=previous_step_id,next_step_id=next_step_id,current_status='idle')
            #we.save()
        return True

attaching the models.py also

from django.db import models

class workflow_details(models.Model):
    workflow_name = models.CharField(max_length=20,)
    workflow_id = models.IntegerField(primary_key=True)
    workflow_status=models.BooleanField()
    def __str__(self):
        return self.workflow_id
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Details'

class workflow_steps(models.Model):
    workflow_id=models.ForeignKey('workflows.workflow_details',to_field='workflow_id',on_delete=models.CASCADE)
    step_id=models.CharField(max_length=20,primary_key=True)
    step_name=models.CharField(max_length=20)
    is_start=models.BooleanField()
    is_end=models.BooleanField()
    previous_step_id=models.CharField(max_length=20)
    next_step_id=models.CharField(max_length=20)
    step_function=models.CharField(max_length=255)

    def __str__(self):
        return self.step_id
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Steps'

class workflow_execution(models.Model):
    workflow_id=models.ForeignKey('workflows.workflow_details',to_field='workflow_id',on_delete=models.PROTECT)
    execution_id=models.CharField(max_length=30,primary_key=True)
    step_id=models.CharField(max_length=20)
    step_name=models.CharField(max_length=20)
    is_start=models.CharField(max_length=5)
    is_end=models.CharField(max_length=5)
    previous_step_id=models.CharField(max_length=20,default='')
    next_step_id=models.CharField(max_length=20,default='')
    start_time=models.CharField(max_length=20,default='')
    end_time=models.CharField(max_length=20,default='')
    execution_time=models.CharField(max_length=20,default='')
    success=models.CharField(max_length=5,default='')
    failure=models.CharField(max_length=5,default='')
    current_status=models.CharField(max_length=10,default='')


    def __str__(self):
        return str(self.execution_id)
    
    class Meta:
        app_label = 'workflows'
        verbose_name_plural = 'Workflow Execution'

i have tried changing the return type for the other models, but still the error persists

Again, I’m going to repeat what I said earlier.

This error has nothing to do with any __str__ function.

Please reread __str__ returned non-string (type int) returned from Model - #6 by KenWhitesell