Django self-recursive foreignkey filter query for all childs
django-filter foreign key
django parent-child relationship
django reverse foreign key
set all in django
how to get data from foreign key django
django foreign key same model
recursive function in django
I have this model with a self referencing Foreign Key relation:
class Person(TimeStampedModel): name = models.CharField(max_length=32) parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
Now I want to get all the multi level children for a person. How do I write a Django query for it? It needs to behave like recursive function.
You can always add a recursive function to your model:
EDIT: Corrected according to SeomGi Han
def get_all_children(self, include_self=True): r = [] if include_self: r.append(self) for c in Person.objects.filter(parent=self): _r = c.get_all_children(include_self=True) if 0 < len(_r): r.extend(_r) return r
(Don't use this if you have a lot of recursion or data ...)
Still recommending mptt as suggested by errx.
Django self-recursive foreignkey filter query for all childs , I have this model with a self referencing Foreign Key relation: class Person(TimeStampedModel): name = models.CharField(max_length=32) I need to be able to run query on a recursive model that gives the name of the parent and child My model class RecursiveModel(models.Model): stage_title = models.CharField(max_length=255, unique=True) parent = models.ForeignKey('self', null=True) I need to get the names of parent and child relationship Equivalant query being:
You should read about Modified preorder tree traversal. Here is django implementation. https://github.com/django-mptt/django-mptt/
Recursive queries as QuerySets for Parent/Child relationships (self , Recursive queries as QuerySets for Parent/Child relationships (self ManyToMany) in Django. Thibaud Nesztler. Follow ForeignKey( "self" If we want to collect all children, we can use Django's ORM and Q filters to return them. These model ForeignKey ('self') class Meta: db_table = 'foos' foo = Foo. objects. select_related (). get (pk = 1) That leads to infinite recursion in django.db.models.query.fill_table_cache. The bottom of the stack trace is:
sunn0's suggestion is great idea, but get_all_children() returns weird results. It returns something like [Person1, [Person3, Person4], []]. It should be changed to like below.
def get_all_children(self, include_self=True): r = [] if include_self: r.append(self) for c in Person.objects.filter(parent=self): _r = c.get_all_children(include_self=True) if 0 < len(_r): r.extend(_r) return r
Recursive Model Relationships in Django, So in "webapp/urls.py" use the following code to direct all routes prefixed with "/hr" to the ForeignKey call, Django will set this up as a recursive relationship. def get_all_children(self, container=None): if container is None: container = [] result = container for child in self.children.all(): result.append(child) if child.children.count() > 0: child.get_all_children(result) return result
If you know the max depth of your tree, you could try something like this (untested):
Person.objects.filter(Q(parent=my_person)|Q(parent__parent=my_person)| Q(parent__parent__parent=my_person))
Models | Documentation de Django, Model . Each attribute of the model represents a database field. With all of this, Django you an automatically-generated database-access API; see Making queries. As with ForeignKey , you can also create recursive relationships (an object Group.objects.filter(members__name__startswith='Paul') <QuerySet [<Group: ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet. See the reference for ModelChoiceField. So, provide a QuerySet to the field’s queryset attribute. Depends on how your form is built. If you build an explicit form, you’ll have fields named directly.
I know this is old, but someone might just get helped.
def get_all_children(self, container=None): if container is None: container = [] result = container for child in self.children.all(): result.append(child) if child.children.count() > 0: child.get_all_children(result) return result
and then simply make this a property
(OR a cached_property
if that works for you) on the model so it can be called on any instance.
Model field reference | Django documentation, This document contains all the API references of Field including the field options For fields like ForeignKey that map to model instances, defaults should be the A regular expression, as a string, that FilePathField will use to filter filenames. be necessary to avoid executing queries at the time your models.py is imported:. django-rest-framework Getting list of all related children objects in parent's serializer Example Assume that, we implement a simple API and we have the following models.
Making queries | Django documentation, Refer to the data model reference for full details of all the various model lookup options. Updating a ForeignKey field works exactly the same way as saving a normal field Filters narrow down the query results based on the given parameters. Note that the select_related() QuerySet method recursively prepopulates the Not able to filter() on foreign keys. I'm trying to filter by a value that is contained in a foreign key. I've seen this done in the django documentation (the
#21584 (prefetch_related child queryset does not update on create , When a child foreign key relationship has been prefetched, calling from django.db import models class Parent(models.Model): pass class Child(models.Model): my_objects = Foo.objects.all().filter(bar=1) list(my_objects) # evaluate query It is a foreign key that defines a recursive relationship between employees and their managers. This means that the implicit auto incrementing integer id column that Django makes on models that inherits from django.db.models.Model will be available as a foreign key value for the same class (or table).
2. How to model one to many relationships?, In a one-to-many relationship, the parent is not required to have child records; therefore, the To define a many-to-one relationship, use ForeignKey .:. The problem is in trim_joins() method of the Query class. This method just trims inner join because the condition is "pk of Child is not null", "pk of Child" is actually a foreign key to parent so trimmer reduces join chain and we finally gets "pk of Parent is not null".
Comments
- Should be get_all_children() as the function call and you need to use r = r + c.get_all_children() or you'll end up with nested lists. I don't seem to have the rights to edit this myself
- Updated code according to comment. If everyone was allowed to edit all posts we would have a big problem :)
- I think this should have
include_self=True
in the inner function call as well. Otherwise, at each recursion we just go down one more level, never actually adding anything tor
. It only worked correctly for me after making that change. - Your solution gives a good notion but is untested. At the end, r is a nested empty list. Please consider fixing it..
- stackoverflow.com/questions/42676085/…
- is it necessary to use third party solution? is there any other way??
- @Ashan: You can always read about it e.g. here: dev.mysql.com/tech-resources/articles/hierarchical-data.html and write the code yourself
- This does not answer the questioner, "get all the multi level children for a person"... This will in fact only get the direct children (i.e. one-level) for a person.
- Thanks @Yeo I must have misunderstood the question. I just updated my response with a similar snippet i have i have in one of my projects.