9

I have some models with relationships like this:

class Item(model.Model):
    name = models.CharField()

class Group(models.Model):
    item = models.ManyToManyField(Item)

class Serie(models.Model):
    name = models.CharField()
    chart = models.ForeignKey(Chart)
    group = models.ForeignKey(Group)

class Chart(models.Model):
    name = models.CharField()

I need to create a Chart object on the fly, without saving to the DB. But I can't do it because Django tries to use the objects primary keys when assigning the relationships.

I just want Group.add(Item()) to work without having to save the objects to the DB.

Is there any simple way around this?

Facundo Casco
  • 10,065
  • 8
  • 42
  • 63

2 Answers2

6

Reviving here for the sake of future readers:

I've gotten around this use case by defining a private attribute that represents the relationship inside the classes and a property to inspect wether the object can be retrieved from the DB or resides in memory.

Here is a simple example:

class Parent(models.Model):
    _children = []
    name = models.CharField(max_length=100)

    @property
    def children(self):
        if _children:
            return self._children
        else:
            return self.children_set.all()

    def set_virtual_children(self, value):  # could use a setter for children
        self._children = value  # Expose _children to modification

    def some_on_the_fly_operation(self):
        print(','.join([c.name for c in self.children]))   


 class Children(models.Model):
     parent = models.ForeignKey(Parent)
     name = models.CharField(max_length=100)

This way, I can set the "virtual children" and use all the defined methods "on the fly"

Alvaro
  • 11,797
  • 9
  • 40
  • 57
0

EDIT: It seems that approach described here isn't enough for django to allow adding to the ManyToMany relationship.

Have you tried to add primary_key=True and unique=True to the name attribute of the Item model. Then doing Group.add(Item("item_name_here")) should work if you have the possibility to create the name on the fly.

I didn't test it, but I think your way failed because add() wants to use the primary-key which by default is the autoincrementing id that is assigned when it is saved to the database.

Lycha
  • 9,937
  • 3
  • 38
  • 43
  • I need to keep the primary key of the models, I just want Djanto not to look for a primary key if I am not trying to save any of the objects. – Facundo Casco Oct 26 '11 at 20:36
  • @FC In that case I would guess it's not possible. Btw. I think even adding the primary key that I suggested wont be enough. – Lycha Oct 26 '11 at 21:09