How to make Django ManyToMany relationships explicit on the receiving model's end












2














Relationships, particularly ManyToMany, in Django have always bothered me somewhat. In particular, since the relationship is only defined in one of the models, you can't tell from looking at the paired model what other relationships it might be hiding.



For example, from the Django Documentation:



class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)


You can tell from looking at the code that I'd find out the relevant toppings for a pizza at Pizza.toppings. But you cannot tell that I would be able to tell what pizzas have a topping at Topping.Pizza_set--you have to look at the Pizza class to see this.



As a result, by looking at Toppings, I don't actually know the full range of fields that it has.



Is there any way around this or to make it more explicit? Or is there something that I'm missing?










share|improve this question






















  • Did you try Topping.Pizza_set.all() ?
    – Victor Castillo Torres
    Aug 8 '13 at 2:50










  • Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
    – jdotjdot
    Aug 8 '13 at 5:07
















2














Relationships, particularly ManyToMany, in Django have always bothered me somewhat. In particular, since the relationship is only defined in one of the models, you can't tell from looking at the paired model what other relationships it might be hiding.



For example, from the Django Documentation:



class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)


You can tell from looking at the code that I'd find out the relevant toppings for a pizza at Pizza.toppings. But you cannot tell that I would be able to tell what pizzas have a topping at Topping.Pizza_set--you have to look at the Pizza class to see this.



As a result, by looking at Toppings, I don't actually know the full range of fields that it has.



Is there any way around this or to make it more explicit? Or is there something that I'm missing?










share|improve this question






















  • Did you try Topping.Pizza_set.all() ?
    – Victor Castillo Torres
    Aug 8 '13 at 2:50










  • Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
    – jdotjdot
    Aug 8 '13 at 5:07














2












2








2







Relationships, particularly ManyToMany, in Django have always bothered me somewhat. In particular, since the relationship is only defined in one of the models, you can't tell from looking at the paired model what other relationships it might be hiding.



For example, from the Django Documentation:



class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)


You can tell from looking at the code that I'd find out the relevant toppings for a pizza at Pizza.toppings. But you cannot tell that I would be able to tell what pizzas have a topping at Topping.Pizza_set--you have to look at the Pizza class to see this.



As a result, by looking at Toppings, I don't actually know the full range of fields that it has.



Is there any way around this or to make it more explicit? Or is there something that I'm missing?










share|improve this question













Relationships, particularly ManyToMany, in Django have always bothered me somewhat. In particular, since the relationship is only defined in one of the models, you can't tell from looking at the paired model what other relationships it might be hiding.



For example, from the Django Documentation:



class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)


You can tell from looking at the code that I'd find out the relevant toppings for a pizza at Pizza.toppings. But you cannot tell that I would be able to tell what pizzas have a topping at Topping.Pizza_set--you have to look at the Pizza class to see this.



As a result, by looking at Toppings, I don't actually know the full range of fields that it has.



Is there any way around this or to make it more explicit? Or is there something that I'm missing?







python django django-models






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 8 '13 at 2:45









jdotjdot

9,09474486




9,09474486












  • Did you try Topping.Pizza_set.all() ?
    – Victor Castillo Torres
    Aug 8 '13 at 2:50










  • Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
    – jdotjdot
    Aug 8 '13 at 5:07


















  • Did you try Topping.Pizza_set.all() ?
    – Victor Castillo Torres
    Aug 8 '13 at 2:50










  • Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
    – jdotjdot
    Aug 8 '13 at 5:07
















Did you try Topping.Pizza_set.all() ?
– Victor Castillo Torres
Aug 8 '13 at 2:50




Did you try Topping.Pizza_set.all() ?
– Victor Castillo Torres
Aug 8 '13 at 2:50












Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
– jdotjdot
Aug 8 '13 at 5:07




Topping.pizza_set.all() is how to get the actual pizzas, which is not the issue--the question is how to make it clear in the actual model that the way to get pizzas is by calling topping.pizza_set.<something>.
– jdotjdot
Aug 8 '13 at 5:07












2 Answers
2






active

oldest

votes


















0














This seems to be an unavoidable side effect of the DRY principle. I don't know of any way to declaratively show the symmetry in these relations (other than by commenting and such). If you really want to make things explicit you could put the relationship in its own table (which Django is doing behind the scenes anyway), like:



class Topping(models.Model):
# ...

class Pizza(models.Model):
# ...

class PizzaToppings(models.Model):
# '+' disables the reverse relationship
pizza = models.ForeignKey(Pizza, related_name='+')
topping = models.ForeignKey(Topping, related_name='+')


... but of course then you'd lose some of the convenience of the ORM.






share|improve this answer





























    0














    Found a way on Django's forum (lost link, sorry)



    class Topping(models.Model):
    explicit_pizza_set = models.ManyToManyField(Pizza, through=Pizza.toppings.through, blank=True)

    class Pizza(models.Model):
    toppings = models.ManyToManyField(Topping)





    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18117113%2fhow-to-make-django-manytomany-relationships-explicit-on-the-receiving-models-en%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      This seems to be an unavoidable side effect of the DRY principle. I don't know of any way to declaratively show the symmetry in these relations (other than by commenting and such). If you really want to make things explicit you could put the relationship in its own table (which Django is doing behind the scenes anyway), like:



      class Topping(models.Model):
      # ...

      class Pizza(models.Model):
      # ...

      class PizzaToppings(models.Model):
      # '+' disables the reverse relationship
      pizza = models.ForeignKey(Pizza, related_name='+')
      topping = models.ForeignKey(Topping, related_name='+')


      ... but of course then you'd lose some of the convenience of the ORM.






      share|improve this answer


























        0














        This seems to be an unavoidable side effect of the DRY principle. I don't know of any way to declaratively show the symmetry in these relations (other than by commenting and such). If you really want to make things explicit you could put the relationship in its own table (which Django is doing behind the scenes anyway), like:



        class Topping(models.Model):
        # ...

        class Pizza(models.Model):
        # ...

        class PizzaToppings(models.Model):
        # '+' disables the reverse relationship
        pizza = models.ForeignKey(Pizza, related_name='+')
        topping = models.ForeignKey(Topping, related_name='+')


        ... but of course then you'd lose some of the convenience of the ORM.






        share|improve this answer
























          0












          0








          0






          This seems to be an unavoidable side effect of the DRY principle. I don't know of any way to declaratively show the symmetry in these relations (other than by commenting and such). If you really want to make things explicit you could put the relationship in its own table (which Django is doing behind the scenes anyway), like:



          class Topping(models.Model):
          # ...

          class Pizza(models.Model):
          # ...

          class PizzaToppings(models.Model):
          # '+' disables the reverse relationship
          pizza = models.ForeignKey(Pizza, related_name='+')
          topping = models.ForeignKey(Topping, related_name='+')


          ... but of course then you'd lose some of the convenience of the ORM.






          share|improve this answer












          This seems to be an unavoidable side effect of the DRY principle. I don't know of any way to declaratively show the symmetry in these relations (other than by commenting and such). If you really want to make things explicit you could put the relationship in its own table (which Django is doing behind the scenes anyway), like:



          class Topping(models.Model):
          # ...

          class Pizza(models.Model):
          # ...

          class PizzaToppings(models.Model):
          # '+' disables the reverse relationship
          pizza = models.ForeignKey(Pizza, related_name='+')
          topping = models.ForeignKey(Topping, related_name='+')


          ... but of course then you'd lose some of the convenience of the ORM.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 8 '13 at 3:07









          Kevin Christopher Henry

          22.5k46361




          22.5k46361

























              0














              Found a way on Django's forum (lost link, sorry)



              class Topping(models.Model):
              explicit_pizza_set = models.ManyToManyField(Pizza, through=Pizza.toppings.through, blank=True)

              class Pizza(models.Model):
              toppings = models.ManyToManyField(Topping)





              share|improve this answer


























                0














                Found a way on Django's forum (lost link, sorry)



                class Topping(models.Model):
                explicit_pizza_set = models.ManyToManyField(Pizza, through=Pizza.toppings.through, blank=True)

                class Pizza(models.Model):
                toppings = models.ManyToManyField(Topping)





                share|improve this answer
























                  0












                  0








                  0






                  Found a way on Django's forum (lost link, sorry)



                  class Topping(models.Model):
                  explicit_pizza_set = models.ManyToManyField(Pizza, through=Pizza.toppings.through, blank=True)

                  class Pizza(models.Model):
                  toppings = models.ManyToManyField(Topping)





                  share|improve this answer












                  Found a way on Django's forum (lost link, sorry)



                  class Topping(models.Model):
                  explicit_pizza_set = models.ManyToManyField(Pizza, through=Pizza.toppings.through, blank=True)

                  class Pizza(models.Model):
                  toppings = models.ManyToManyField(Topping)






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 11 at 23:12









                  Guillaume Lebreton

                  545516




                  545516






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18117113%2fhow-to-make-django-manytomany-relationships-explicit-on-the-receiving-models-en%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Xamarin.form Move up view when keyboard appear

                      Post-Redirect-Get with Spring WebFlux and Thymeleaf

                      Anylogic : not able to use stopDelay()