Django – One to One field sometimes not saving the value assign on field after save call without errors

Question:

We are currently experiencing an issue with a one-to-one field in Django where the data was not stored after assigning a value and save call is successful without any error. This does not happen to all the records. I’d say 60% of it was not saving and 40% was saving. This only happens on our production server where there are millions of rows for Model1 and Model2 and there are so many processes ongoing. We also assign a value to other fields and call save on other parts of the process after the link_item method is called.

models.py

class Model2(models.Model):
    # Some other fields here

class Model1(models.Model):
    field1 = models.OneToOneField(Model2, on_delete=models.SET_NULL, null=True, blank=True, default=None) 
    # Some other fields here

    def link_item(self, model2_id):
        logger.info(f'Linking {self.id} to {model2_id}')
        field1 = Model2.objects.get(id=model2_id)
        self.field1 = field1
        self.save()
        logger.info(f'Field 1 was set to {self.field1}')

views.py

import module

def my_view(requests):
    model1_obj = Model1.objects.get(id=model1_id)
    result = module.another_function(model1_obj, request_data)
    return result

module.py

def another_function(model1_obj, request_data):
    logger.info(f'Request data was {request_data}')
    if request_data['status'] == 'completed':
        model1_obj.some_process() # .save() is called here after assigning a value to attribute
        model1_obj.some_process2() # .save() is also called here after assigning a value to attribute
        model1_obj.link_item(request_data['model2_id']) # Logs were shown but field1 value was not set

I can see all the logs on the server were correct but when I checked the value of the field1 sometimes it doesn’t get updated with the expected value. We are using Django 4.0 and Postgres 14. Any idea why?

Asked By: michael ababao

||

Answers:

This has been resolved. So the problem is we have a celery task that updates the same model1_obj causing the data to be overridden because it also calls the save method on the task. We fixed it by adding the specific field to update on the celery task like this: save(update_fields=[‘field_name’])

Answered By: michael ababao