Olivier Pons
Olivier Pons

Reputation: 15778

Django Manytomany filter with intermediate model

I have the following models:

class Personne(BaseModel):
    user = models.OneToOneField(User)
    relations = models.ManyToManyField('self', through='PersonneRelation',
                                       symmetrical=False,
                                       related_name='personne_relations')

class PersonneRelation(BaseModel):
    type_relation = models.IntegerField(
        choices=[(a, b) for a, b in list(PersonneEnums.TAB_RELATIONS.items())],
        default=PersonneEnums.RELATION_FRIEND)
    src = models.ForeignKey('Personne', related_name='relation_src')
    dst = models.ForeignKey('Personne', related_name='relation_dst')

In my view, I have the currently logged user via

p_user = Personne.objects.get(user=view.request.user)

I want to retrieve all the relation of p_user that are of type PersonneEnums.RELATION_FRIEND

I've tried many things including the following code, but nothing works:

Doesn't work :

p_user.objects.filter(relations__type_relation__exact=PersonneEnums.RELATION_AMI)

Doesn't work:

Personne.objects.filter(
    pk=p_user.pk,
    relations__type_relation__exact=PersonneEnums.RELATION_AMI
)

Can someone explain to me why this does not work?

Upvotes: 4

Views: 980

Answers (1)

Nikita
Nikita

Reputation: 6331

In both cases you're trying to use the default manager objects, while you need to use a relationship manager. However it seems, that there will be a problem as relationship is ambiguous, i.e. when querying relationship like this:

p_user.relations.filter(type_relation=PersonneEnums.RELATION_AMI)

Django couldn't decide if it should use src or dst in this query.

The following query should work:

PersonneRelations.objects.filter(
    Q(type_relation=PersonneEnums.RELATION_AMI), Q(src=p_user) | Q(dst=p_user))

also, something like this might work (see explanation on filter):

p_user.relations.filter(relation_src__type_relation=PersonneEnums.RELATION_AMI
               ).filter(relation_dst__type_relation=PersonneEnums.RELATION_AMI)

Upvotes: 2

Related Questions