How do I retrieve a field from a Many-To-Many table?

44 Views Asked by At

I need to retrieve a value from a Many-To-Many query. Let's say I have 3 models: Toy, Part, and ToyParts

ToyParts has a field called "part_no". I need to be able to get the value of this.

class Toy(models.Model):
    parts = models.ManyToManyField(Part, through="ToyParts")

class Part(models.Model):
    pass

class ToyParts(models.Model):
    toy = models.ForeignKey(Toy, ...)
    part = models.ForeignKey(Part, ...)
    part_no = models.CharField(...)

I've tried using:

toy.parts.all().first().part_no

which obviously doesn't work as Part does not have a field called "part_no"

I've also tried just simply using:

ToyParts.objects.filter(toy=..., part=...)

but that adds additional queries.

How would I be able to get part_no without querying ToyParts directly?

1

There are 1 best solutions below

0
ikkuh On

I've tried using: toy.parts.all().first().part_no

The part_no field is declared on the model ToyParts. You therefore need to get an instance of ToyParts to access this field. Assuming you have a Toy instance you can use the reverse relation to ToyParts, which defaults to toyparts_set, as follows:

toy.toyparts_set.first().part_no

How would I be able to get part_no without querying ToyParts directly?

You can't. If you want to reduce the number of queries you can use select_related:

for tp in toy.toyparts_set.select_related('part').all():
    print(tp.part_no, tp.part.id)

In this example tp.part doesn't require an extra query as the part instance is already fetched by select_related.