Code

Opened 4 years ago

Closed 4 years ago

#14113 closed (invalid)

Access to extra fields in M2M relations

Reported by: jprafael Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords: Many2ManyField intermediary fields
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I'm using a model similar to

class Recipe(models.Model):
        name = models.CharField(max_length = 32, unique=True)
        products = models.ManyToManyField(Product, through="RecipeProduct")

class Product(models.Model):
        name = models.CharField(max_length = 32, unique=True)

        amound = models.IntegerField() # in stock

class RecipeProduct(models.Model):
        recipe = models.ForeignKey(Recipe)
        product = models.ForeignKey(Product)

        amount  = models.IntegerField()

And need to list all my recipes, along with their products' amounts.

Recipe.objects.select_related().all()

Gives access to the list of products in each recipe, but not access to the amount field in the intermediary table.

Perhaps recipe.products.all() should merge the extra fields into the Product objects by means of another parameter in the ManyToManyField definition where the user can choose the fields to select (and the names they would be accessible by) like:

products = models.ManyToManyField(Product, through="RecipeProduct", extra_fields={'amount': 'recipe_amount'})

This would allow direct usage like:

{% for recipe in recipes %}
        {% for product in recipe.products.all() %}
                product: {{ product.name }} ({{ product.amount }} in stock)
                amount: {{ product.recipe_amound }}
        {% endfor}
{% endfor %}

while avoiding name colision problems

Attachments (0)

Change History (1)

comment:1 Changed 4 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

This is already possible -- you just need to think about your data model in a slightly different way, and look at the intermediate model as a fully-fledged model with a foreign key:

{% for recipe in recipes %}
    {% for rp in recipe.recipeproduct_set.all %}
		product: {{ rp.product.name }} ({{ rp.product.amount }} in stock)
		amount: {{ rp.amount }}
    {% endfor %}
{% endfor %}

Merging the attributes of the intermediate class onto the m2m objects was considered at the time the m2m-intermediate feature was under development, and was rejected. Search the archives and ticket #6095 for reasoning.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.