简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM