0

There have been some close ones on this, but all I can find is what I'm doing and its not working.

Here is an example: You have a product which can have multiple options. Each option can have multiple choices.

class Option_Choices(models.Model):
    """
    choices for each option
    """
    name = models.CharField(max_length=30)

    def __unicode__(self):
        return self.name


class Product_Options(models.Model):
    """
    products can have many options
    """
    name = models.CharField(max_length=30)
    option_type = models.IntegerField(choices=OPTION_TYPE)
    choices = models.ManyToManyField(Option_Choices, related_name='product_options_choices')

    def __unicode__(self):
        return self.name


class Product(models.Model):
    """
    there are options for products - different sizes / colors
    """
    name = models.CharField(max_length=30)
    options = models.ManyToManyField(Product_Options, related_name='product_options')

    def __unicode__(self):
        return self.name

Looks simple enough, I get this error

'options' is a manually-defined m2m relation through model Product_Options, which does not have foreign keys to Product_Options and Product

I've tried a ton of different things, including using "through" can't figure out why this isn't working. its what everyone says to do. any ideas?

AndrewS
  • 1,666
  • 11
  • 15
Jason G
  • 2,395
  • 2
  • 24
  • 34

1 Answers1

3

I usually reverse m2m definitions as below. In your code above you're seeing a conflict in table names due to the underscore in your model class names. If you remove the underscores it should work.

Reversing the relationships could work if you want to keep the underscores.

class Option_Choices(models.Model):
    """
    choices for each option
    """
    name = models.CharField(max_length=30)
    product_options = models.ManyToManyField("Product_Options", related_name='choices')


class Product_Options(models.Model):
    """
    products can have many options
    """
    OPTION_TYPE=(
        ('Color', 1),
    )
    name = models.CharField(max_length=30)
    option_type = models.IntegerField(choices=OPTION_TYPE)
    products = models.ManyToManyField("Product", related_name='options')


class Product(models.Model):
    """
    there are options for products - different sizes / colors
    """
    name = models.CharField(max_length=30)
AndrewS
  • 1,666
  • 11
  • 15
  • "Reversing" the M2M relationship is wrong. See [the docs](https://docs.djangoproject.com/en/dev/topics/db/models/) – hobs Mar 03 '14 at 20:22
  • @hobs Could you elaborate? – AndrewS Mar 04 '14 at 06:44
  • I misunderstood what you meant by "reverse". I thought you were reversing the direction of the relationships by putting FK fields in opposite tables and I didn't scroll far enough to the right to see that you hadn't defined Option_Choices as an explicit `through` model. Can't put M2M's in a through table... but you haven't, so you're OK. That's what I get for skimming. – hobs Mar 04 '14 at 19:06