How do I query on two incoming models using the Django ORM?
I've got the following models:
class DataStream(models.Model):
category = models.CharField(max_length=255)
description = models.TextField()
class DataStreamSubCategory(models.Model):
data_stream = models.ForeignKey(DataStream)
sub_category = models.CharField(max_length=255)
class DataStreamExample(models.Model):
data_stream = models.ForeignKey(DataStream)
example = models.CharField(max_length=255)
So, each DataStream
can have 0 or more DataStreamSubCategory
objects and 0 or more DataStreamExample
objects.
What I want to do is essentially display these values in a simple table in a template:
----------------------------------------
| Category | Sub-categories | Examples |
----------------------------------------
| Cat1 | Sub-cat1 | Ex1 |
| | Sub-cat2 | Ex2 |
| | Sub-cat3 | |
----------------------------------------
| Cat2 | Sub-cat4 | Ex1 |
| | | Ex2 |
----------------------------------------
So what's the best way to query the database to get these data? The most obvious (but probably dumb) way is to do this:
data_streams = DataStream.objects.all()
for data_stream in data_streams:
sub_categories = DataStreamSubCategory.objects.filter(data_stream=data_stream)
examples = DataStreamExample.objects.filter(data_stream=data_stream)
But is there a more efficient way? Seems like a few SQL joins should be in order here, but I'm not sure how to accomplish this using the Django ORM.
You can query it directly in the template like this:
<table>
{% for ds in data_streams %}
<tr>
<td>
{% ds.category %}
</td>
<td>
{% for subcat in ds.datastreamsubsategory_set.all %}
{{subcat.sub_category}}
{% endfor %}
</td>
<td>
{% for example in ds.datastreamexample_set.all %}
{{example.example}}
{% endfor %}
</td>
{% empty %}
<tr><td colspan="3">No categories found</td></tr>
{% endfor %}
</table>
I shall let you figure out the formatting yourself.
In the context, just send {'data_streams': data_streams}
Basically, for reverse foreign key relationships, you would do object.lowercasemodelname_set.all()
to get the related object queryset.
Read more on lookups that span relationships here
Or you could add a related_name
attribute and use that instead of lowercasemodelname_set
You might want to even consider prefetch_related
option if you want to reduce the number of queries on the database
上一篇: 使用django创建许多对象