Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to follow ForeignKey('self') backwards

class Achievement(MyBaseModel):
    parent_achievement = models.ForeignKey('self', blank=True, null=True, help_text="An achievement that must be done before this one is achieved") # long name since parent is reserved

I can do :

Achievement.objects.get(pk="1").parent_achievement

which is great. But how do I get all the children?

Achievement.objects.get(pk="1").parent_achievement_set

doesn't work (and probably should have some more notation around it), and I didn't see too much when searching.

Is it possible? Fall into SQL?

like image 965
Paul Tarjan Avatar asked Jul 12 '09 00:07

Paul Tarjan


People also ask

What does ForeignKey mean in Django?

What is ForeignKey in Django? ForeignKey is a Field (which represents a column in a database table), and it's used to create many-to-one relationships within tables. It's a standard practice in relational databases to connect data using ForeignKeys.

What is reverse relation in Django?

Thats' where related name or the reverse relationship comes in. Django, by defaults gives you a default related_name which is the ModelName (in lowercase) followed by _set - In this case, It would be profile_set , so group. profile_set . However, you can override it by specifying a related_name in the ForeignKey field.

What is the difference between ForeignKey and OneToOneField?

The only difference between these two is that ForeignKey field consists of on_delete option along with a model's class because it's used for many-to-one relationships while on the other hand, the OneToOneField, only carries out a one-to-one relationship and requires only the model's class.


1 Answers

By default, django will call the reverse the model name, followed by "_set", so it would be

Achievement.objects.get(pk="1").achievement_set

If that doesn't suit you, use the related_name optional argument to models.ForeignKey:

class Achievement(MyBaseModel):
    parent_achievement = models.ForeignKey(
        'self', 
        blank=True, 
        null=True, 
        help_text="An achievement that must be done before this one is achieved",
        related_name="child_achievement_set"
    ) # long name since parent is reserved

Achievement.objects.get(pk="1").child_achievement_set
like image 150
SingleNegationElimination Avatar answered Oct 17 '22 16:10

SingleNegationElimination