Search code examples
pythondjangodjango-modelsdjango-database

Temporary model instances referenced as foreign keys


Is there a way to keep a Django model instance, which is referenced by foreign keys, in memory without storing it to the database?

The code is part of an _add_ overload, but the way it is implemented now is very ugly as it is hard to keep track of the new instances, and it also produces a lot of unnecessary DB accesses. Ideally I want to keep the new instances temporary as long as the user does not call the save() method on the returned instance.

When I uncomment the save() calls like below, the SequenceAnnotation instances are not referenced in the returned Sequence instance.

    def __add__(self, other: Union['Sequence', str]):
        """
        This enables you to use the + operator when dealing with Sequence objects
        :param other:
        :return:
        """
        sum_seq = Sequence()

        # concatenate the actual sequences
        sum_seq.sequence = self.sequence + other.sequence

        #sum_seq.save()
        len_self_seq = len(self.sequence)

        # annotations
        annot: SequenceAnnotation
        # copy the own anntotations
        for annot in self.annotations.all():
            new_annot = deepcopy(annot)
            new_annot.id = None  # this is crucial to actually create a new instance
            new_annot.ref_sequence = sum_seq
            #new_annot.save()


        # copy the other annotations, adjust the start and end positions
        for annot in other.annotations.all():
            new_annot = deepcopy(annot)
            new_annot.id = None  # this is crucial to actually create a new instance
            new_annot.start = len_self_seq + annot.start
            new_annot.end = len_self_seq + annot.end
            new_annot.ref_sequence = sum_seq
            #new_annot.save()

        return sum_seq

Solution

  • No, as far as I know.

    Django foreign key fields are backed by something_id fields; assigning foo.something to something that has a None id sets the backing field to None.

    You would need to implement something similar to how forms (may) have save_m2m() to ensure the constellation of objects gets saved in the right order.