Raymond Seger
Raymond Seger

Reputation: 1130

How do i get field data from "through" ManyToMany object?

I have been having trouble on how to get that "group" data in ProductInsideCombo, this is a ManyToMany object that is linked with "through". I need to get the "group" data, Please help.

These are my two models:

@python_2_unicode_compatible
class ProductInsideCombo(models.Model):
    parent  = models.ForeignKey('Product', related_name='+')
    child   = models.ForeignKey('Product', verbose_name="Products inside the combo", related_name='+')
    group   = models.CharField(
        max_length=255,
        choices=(
            ('group_1', 'Group 1'),
            ('group_2', 'Group 2'),
        ),
        default='group_1',
    )

    def __str__(self):
        return str(self.id)


@python_2_unicode_compatible
class Product( models.Model ):
    name    = models.CharField(verbose_name="Name"), max_length=255)
    slug    = models.SlugField(verbose_name="Slug"), max_length=255, unique=True)

    price       = models.PositiveIntegerField(verbose_name='Price', null=True, blank=True)
    sale_price  = models.PositiveIntegerField(verbose_name="Sale Price", null=True, blank=True)

    products_inside_combo   = models.ManyToManyField('self', through='ProductInsideCombo', symmetrical=False, help_text="Only for Combo Products", blank=True)

    created         = models.DateTimeField(default=now)
    modified        = models.DateTimeField(editable=True, auto_now=True)

    def __str__(self):
        return "%s" % (self.sku, )

    class Meta:
        verbose_name        = "Product"
        verbose_name_plural = "Products"

This is what i tried:

the_product     = Product.objects.all().filter(id=5).first() # simplified query for stackoverflow

for one_product in the_product.products_inside_combo.all().order_by('products_inside_combo__id'):
        try1 = one_product.group # fail
        try2 = one_product.products_inside_combo__group # fail too!
        try3 = one_product.products_inside_combo.group # fail
        product_id = one_product.id

This is the current way i am doing it that can work, but i feel like it's a bad query:

 for one_product in the_product.products_inside_combo.all().order_by('products_inside_combo__id'):
        product_id          = one_product.id # child id
        # to get the Group data
        the_product_inside_combo    = ProductInsideCombo.objects.all().filter(parent__id=the_product.id, child__id=product_id).first()
        the_group_data              = the_product_inside_combo.group # this is what i want
        product_name        = one_product.name

Upvotes: 0

Views: 81

Answers (1)

neverwalkaloner
neverwalkaloner

Reputation: 47364

You can add related_name to your ProductInsideCombo model:

class ProductInsideCombo(models.Model):
     parent  = models.ForeignKey('Product', related_name='children')

and use this to iterate over all product's productinsidecombos:

for one_product in the_product.children.all().order_by('id'):
    try1 = one_product.group # will fetch group

Upvotes: 1

Related Questions