How to access a parent model from one of my fk fields?

I'am trying to access a parent instance from its child.

I have the following models

class ModelA(models.Model):
   user_name = models.Charfield()
   points = models.Charfield()

class ModelB(models.Model):
   user = models.ForeignKey(ModelA)
   points = models.Charfield()

class ModelC(models.Model):
   model_b = models.OneToOne(ModelB)
   info = models.TextField()

And I'am doing a query like this:

ModelB.objects.filter({somefilters}).values('user__user_name')

But I want to check if there is a reference to B in C, and if there is get the info. I can't start from ModelC as:

ModelC.objects.filter({somefilers}).values('model_b__user__user_name')

Because there maybe or not a record relating both models.

Is possible starting from ModelB to get info from its parent ModelC?

Upvotes: 1

Views: 61

Answers (2)

Caio Kretzer
Caio Kretzer

Reputation: 169

You can use a related name on Model C like:

class ModelC(models.Model):
   model_b = models.OneToOne(ModelB, related_name='modelc')
   info = models.TextField()

And in your queryset:

ModelB.objects.filter({somefilters}).values('user__user_name', 'modelc__info')

If you don't want to set a related name you can use: model_b_set__info instead of modelc__info

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476574

Yes, you can make use of the __isnull lookup [Django-doc] here:

ModelB.objects.filter(
    modelc__isnull=False
).values('user__user_name')

Here we thus check if there is a ModelC that points to that ModelB object.

You can access the related modelc object as well, for example in your values, like:

ModelB.objects.filter(
    modelc__isnull=False
).values('user__user_name', 'modelc__info')

This will thus result in a JOIN where we JOIN the ModelC.model_b field on the ModelB.pk.

If you use:

ModelB.objects.values('user__user_name', 'modelc__info')

It will return None for modelc__info given no such related ModelC exists.

Upvotes: 1

Related Questions