Extra fields on many-to-many relationships¶

i have a many-to-many to it self, and i try access the same information by querying the [many-to-many reverse relationship] from my Model object, like in documentation. But not works, always get “object has no attribute”.

Its because its a many-to-many to it self? Is there a solution, or workaround?

Another way to access the same information is by querying the many-to-many reverse relationship from a Person object:

>>> ringos_membership = ringo.membership_set.get(group=beatles) 
>>> ringos_membership.date_joined datetime.date(1962, 8, 16) 
>>> ringos_membership.invite_reason 'Needed a new drummer.'

https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

A ManyToMany to self is going to have two Foreign Keys to the same model. When that occurs, you need to use the related_name attribute for each of those ForeignKey fields.

So remember that when you’re accessing a ForeignKey “backwards”, you need to refer to it by the related name of that foreign model. You need to tell Django which “direction” to follow to identify elements of that through table.

I have my models like this:

class ArticleVersion(models.Model):
    articles_versions_childs = models.ManyToManyField("self", verbose_name="Artigo Versão Filhos", related_name='children', symmetrical=False, blank=True, through='Article_Version_Child')
class Article_Version_Child(models.Model):
    from_article_version = models.ForeignKey(ArticleVersion, on_delete=models.CASCADE, related_name='from_article_version')
    to_article_version = models.ForeignKey(ArticleVersion, on_delete=models.CASCADE, related_name='to_article_version')
    quantity = models.IntegerField(verbose_name="Quantidade", null=True, blank=True, default=1)
    

Follow the document, i try article_version.article_version_child_set(to_article_version=my_other_article_version)

That’s not the related name.

If you have an instance of ArticleVersion named article_version, then the set of Article_Version_Child that relates to article_version by the to_article_version FK field would be to_article_version.

(Review the docs at Making queries | Django documentation | Django)

i follow this sample of docs

ringos_membership = ringo.membership_set.get(group=beatles)
article_version.article_version_child_set.get(from_article_version=article_child)

instance of ArticleVersion = article_version / ringo
name of manytomany table _set = article_version_child_set / membership_set
get name of field and other instance = .get(from_article_version=article_child) / .get(group=beatles)

That analogy doesn’t directly apply. The membership set that you are referencing from the example does not use a related name attribute in its ForeignKey definition.

Again,

is not the related name used here.

Review the docs and the examples at Making queries | Django documentation | Django

This is my reverse and it works.

article_version.children

but i want to get the “quantity” from my manytomany table, how can i get?

I can get all related objects from parent to child and inverse, but I can’t get the data from manytomany table…

As answered before:

Keep in mind that this is a set. There isn’t just one quantity , there’s a quantity for each element of the set.

I know that, i can get quantity this way(this works fine):

m2m = Article_Version_Child.objects.get(from_article_version=article_child, to_article_version=article_version)
print (m2m.quantity)

But i like to get from on instace. Like in the docs:

If you need to access a membership’s information you may do so by directly querying the Membership model:

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

Another way to access the same information is by querying the many-to-many reverse relationship from a Person object:

>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

First sample i can do it, second no. Can you help to do it?

I have now answered that question twice.

You access the through table entries using the related name manager for the aspect of the relationship you wish to use for the query.

It may help if you provide a tangible example for your models using a sample of the data that you are working with. You’re continuing to rely upon an example that does not directly apply to your situation.

article_version.to_article_version.first.quantity

I think I got it, and this worked, I just need to replace the first one with the related instance.

Now i just need to remove de “first” and add the filter for my instace? How can i do it?

How do you apply any filter to a queryset?

Right, I’ll see how I can do it in the template. Thank you and my apologies

Nope, templates not the right place for that. You want to identify the data to be rendered in the view.