Reputation: 1378
I am setting up webservices for an application and I have the following models:
class Parent(models.Model):
...
class Child(models.Model):
parent = models.ForeignKey(Course)
...
The relation is One to Many (1 Parent, many Children)
Now, I would like to get all the Parent objects with its particular Child and send it as a JSON Request.
Is it possible to do so without having to first get all the "Childs" and iterate through them looking for the ones related to the particular parent?
I think that would be extremely inefficient for really large databases, plus the "Childs" won't be repeated in other "Parents"
Thank you very much
Upvotes: 5
Views: 12524
Reputation: 5115
Yes, in django you can use:
parentInstance.child_set.all()
where parentInstance
is one particular parent in your Parent
database. That will return all of the Child objects associated with it in an efficient manner. To make it a JSON response, you can try something like this:
import json
from django.http import HttpResponse
response_data = {}
response_data[str(parentInstance)] = parentInstance.child_set.all()
return HttpResponse(json.dumps(response_data), content_type="application/json"
adopted from here.
Upvotes: 0
Reputation: 53649
Every relationship in Django automatically gets its reverse relation added to the model. In the case of a ForeignKey
or ManyToManyField
that relation contains several objects. In that case, the default attribute name is set to <model>_set
, so in this case child_set
. This is a manager and can be used as such, so e.g. to iterate over all children:
for child in parent.child_set.all():
do_something()
You can also specify the attribute name used for the reverse relation using the related_name
attribute:
class Child(models.Model):
parent = models.ForeignKey(Parent, related_name='children')
for child in parent.children.filter(some_field=True):
do_something()
Read more in the documentation on following relations backwards and how are backward relationships possible.
Upvotes: 18
Reputation: 599470
Why would you need to iterate? Even if Django didn't provide you with a special backwards syntax, you could always do this:
Child.objects.filter(parent=my_parent)
but as a cursory Google for the title of your question would have shown, there is a special syntax for backwards relations:
my_parent.child_set.all()
Upvotes: 2