-1

The Django docs describe how to query reverse m2m fields: https://docs.djangoproject.com/en/1.8/topics/db/queries/#many-to-many-relationships

According to this answer we should use related_name as the first argument in the query.

But I'm having trouble making this work. (I'm using Django 1.8.5). Here are my example models:

class Nlpneutralfeature(models.Model):   
    neutral_feature = models.CharField(u'found word', max_length=255, default='')   

class Userproject(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="project", verbose_name=("owner"))
    monitoring_words = models.ManyToManyField(Nlpneutralfeature, null=True, blank=True, related_name="monitoringwords")        
    name = models.CharField(u'Название проекта', unique=True, max_length=255)

So, to get all Nlpneutralfeature rows that belong to Userproject where Userproject.name == '48', I need to do:

Nlpneutralfeature.objects.filter(userproject__monitoringwords__name='48')

But this does not work. The error I get is: Cannot resolve keyword *'userproject'* into field.

So, Django cannot understand that 'userproject' is lowercased model name Userproject.

Now, this is working:

Nlpneutralfeature.objects.filter(monitoringwords__name='48')

How does Django know that monitoringwords is related_name? No error is strange to me, sicne there is no monitoringwords field in the Nlpneutralfeature model!

Community
  • 1
  • 1
Vic Nicethemer
  • 1,081
  • 3
  • 16
  • 38

2 Answers2

3

Note the phrasing in the Django docs:

The name to user for the relation from the related object back to this one. It's also the default value for related_query_name (the name to use for the reverse filter name from the target model).

In your example, the "target model" is Nlpneutralfeature. When you set related_name = 'monitoringwords' on the ManyToManyField Userproject.monitoringwords, it tells Django to use that related_name to refer from Nlpneutralfeature model objects back to the corresponding Userproject model objects.

Correspondingly, if you had declared Userproject.monitoringwords with related_name = 'foo', the way to query for all Nlpneautralfeatures belonging to project 48 would be: Nlpneautralfeature.objects.filter(foo__name='48').

zachwf
  • 93
  • 4
1

the related_name here is so you can get your Userproject models related to an Nlpneutralfeature model. eg:

nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.monitoringwords.all()

if you didn't declared a related_name then you had to do it like this:

nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.Userproject_set.all()

i think you understaned this property by inverse.. in my opinion i thing you should declare it here like this: related_name="user_projects"

in summary, related_name is to use when you want to get the current models(where you declare your M2M relationship) from the related model.

Soufiaane
  • 1,737
  • 6
  • 24
  • 45