Mrs. Bean Mrs. Bean - 7 months ago 29
Python Question

Django many to many doesn't work in unittest but works in admin

I have two models related through a Many-to-many field.

class Tires(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
brand = models.CharField(max_length=50)

class Car(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
brand = models.CharField(max_length=50)
tires = models.ManyToManyField('Tires', blank=True)


It works fine when I add tires to a car through the admin page, but it does not work in my unittests and I can't figure out what the problem is (probably something really simple)

This is my unittest:

def test_many_to_many(self):
tires_1 = Tires(brand='bridgestone')
tires_1.save()
car_1 = Car(brand='BMW')
car_1.save()
car_1.tires.add(tires_1)
car_1.save()


This doesn't raise any exceptions, but when I print car_1.tires, it says carthings.Tires.None
I've tried it the other way around, adding car_1 to tires_1.car_set but that gives the same result. I've also tried adding an object of a different class in the many-to-many field just to see what would happen, that does raise an error. So it looks like the adding works but it just doesn't save or something?

Answer

You are probably doing this:

>> print car_1.tires
carthings.tires.None

Which is a representation of the "related objects manager". You probably want to do something like:

>> print car_1.tires.all()
[<Tire 1>]

Which returns a queryset, and its representation is more meaningful, since it actually performs a query to show the first elements in the relationship.

By the way, you don't need to save the model after adding something to the tires relationship, since you don't need to update the Cars table.