5

I have 2 apps that are distinct and have no particular reason to talk to each other. This means I don't want to import either name in either app. All the work should be within a glue app.

I would like to write a glue app that would join to particular models via a ManyToManyField like:

In app customers,

class Customer(models.Model):
    ...

In app pizzas,

class Pizza(models.Model):
    ...

Then I would like to write the pizza-selling app that would go like this:

class PizzaSold(models.Model):
    customer = models.ForeignKey(related_name='pizzas')
    pizza = models.ForeignKey(related_name='customers')

    objects = ManyRelatedManager()

so I can access pizzas from customers directly

 pizza = Pizza.objects.all()[0]
 for customer in pizza.customers:
     #Do something cool

and customers from pizza within this new app.

How can I do that ?

Narsilou
  • 321
  • 1
  • 2
  • 6
  • Which version of Django are you using? Where did you find out this ManyRelatedManager? Where do you import it from? – jsalonen May 25 '11 at 09:41

1 Answers1

4

What if you used ManyToManyField to model pizzas sold inside Customer model?

class Customer(models.Model):
   pizzas_bought = models.ManyToManyField(Pizza)

Also, if you wish to add extra data to your customer -> pizza relations, specify the mapping Class with through parameter:

class Customer(models.Model):
   pizzas_bought = models.ManyToManyField(Pizza, through=PizzaSold)

class PizzaSold(models.Model):
   customer = models.ForeignKey(Customer)
   pizza = models.ForeignKey(Pizza)

Simlarly, using related_name should work just fine with ManyToManyFields as well. For instance:

class Customer(models.Model):
   pizzas_bought = models.ManyToManyField(related_name='pizzas')
jsalonen
  • 29,593
  • 15
  • 91
  • 109
  • +1 for point to ManyToManyfield with "through" parameter. That seems to be the standard approach. – Shawn Chin May 25 '11 at 09:48
  • Ok, I might not have been specific, I don't want / cannot use the name pizza in the customer app, which is why I don't want / cannot use this standard approach. I might have to resort to it... – Narsilou May 25 '11 at 10:12
  • You mean you cannot use the class "Pizza"? Then why cannot you use related_name='pizzas' instead? – jsalonen May 25 '11 at 10:13
  • Hm related_name sort of works, but it's still not as convenient as ManyToManyField which automatically joins the tables. I could do it manually of course. – Narsilou May 25 '11 at 10:17
  • Why not use pizzas_bought = models.ManyToManyField(related_name='pizzas') inside Customer class? – jsalonen May 25 '11 at 10:21
  • Because that means that customer_app now depends on pizza_app, which I don't want. – Narsilou May 25 '11 at 11:38
  • How about doing it other way around: class Pizza(models.Model): buyers = models.ManyToManyField(related_name='customers') – jsalonen May 25 '11 at 11:43
  • Same problem, I don't really think pizza_app should depend on customer_app. That's the solution I am implementing right now, but it feels wrong – Narsilou May 25 '11 at 11:55
  • 1
    I see. I have to ask the obvious: why you need to keep pizza and customer models in separate apps if they are so tightly coupled? – jsalonen May 25 '11 at 11:59
  • It looks like you have typos in the PIzzaSold class definition. The ForeignKeys should be the other way around. – Dylan Jun 19 '21 at 14:16