# Could anyone please explain use cases for relationships between models when using FKs?

**URL:** <https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714>\
**Category:** Using Django\
**Created:** [November 28, 2021, 8:23pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714 "2021-11-28T20:23:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![swills1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/swills1/32/6475_2.png) [@swills1](https://forum.djangoproject.com/u/swills1)\
**Post date:** [November 28, 2021, 8:23pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714/1 "2021-11-28T20:23:58Z")

</div>

To preface, I come from a SQL background.

I have these two models;

```auto
Class EventType(models.Model):
    event_type_id = models.AutoField(primary_key = True)
    event_type = models.CharField(max_length=10)
    event_priority = models.IntegerField()
    
    class Meta:
        managed = True
        db_table = 'app_event_type'
        
class Event(models.Model):
    event_id = models.AutoField(primary_key = True)
    event_name = models.CharField(max_length=25)
    event_type = models.ForeignKey(EventType, on_delete=models.CASCADE)
    is_active = models.BooleanField(default=False)
    
    class Meta:
        managed = True
        db_table = 'app_event'

```

I’ve been playing around in the Shell to see what I can do.

Here is one test. This is really cool because oyu can filter using criteria from each model together.

```auto
>>> from app_test.models import *
>>> ee = EventType.objects.get(event_type_id=1).event_set.all()
<QuerySet [<Event: Event object (2)>, <Event: Event object (3)>]>
>>>

```

But I am not understanding the practicality / purpose. I am not saying there isn’t one / any - I am saying I don’t see it and am hoping someone can shed some light.

I assume you’re supposed to add something like this to the end of your Model classes. That way it actually returns something useful rather than IDs.

```auto
def __str__ (self):
    # return {self.event_name}

```

But what would you use these for? I guess when I need to return the type of something this makes it easy for me, but I feel like that is super limited. Which makes me feel like I am missing something pretty major.

What are some common use cases for these relationships / reverse relationships? Is it simply a way to join data with no work on our part? Meaning, django just handles the JOINs for us and then we architect our app to utilize that the best way possible to meet our needs, or are their some intended use cases?

Thanks.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 29, 2021, 1:13pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714/2 "2021-11-29T13:13:24Z")

</div>

> [@swills1](#):
>
> Is it simply a way to join data with no work on our part? Meaning, django just handles the JOINs for us and then we architect our app to utilize that the best way possible to meet our needs, or are their some intended use cases?

Effectively, yes.

First, what you get back from these querysets are instances of the corresponding model, not just the IDs. The default ` __str__ ` method prints the IDs, but in your code, you have the complete object available to you.

The statement `ee = EventType.objects.get(event_type_id=1)` means that `ee` contains a reference to an instance of EventType. You have direct access to each of the fields in that model as `ee.event_type` and `ee.event_priority`.

When you extend that statement to become `ee = EventType.objects.get(event_type_id=1).event_set.all()` you have effectively shortened these two statements to one:

```auto
et = EventType.objects.get(event_type_id=1)
ee = et.event_set.all()

```

In either case (1 statement or 2 since they are effectively the same), ee contains a reference to a queryset, but it is a queryset of `Event`, not `EventType`

As with any other queryset, you can iterate over those results, and access the individual fields of the Event model.  
e.g.

```auto
for an_event in ee:
    print(an_event.name, an_event.type)

```

Side note 1: Personally, I am not a fan of this formulation.  
(This being `EventType.objects.get(event_type_id=1).event_set.all()`) It’s not obvious to me that what is being selected are Event objects and not EventType objects. I would typically recommend:  
`Event.objects.filter(event_type_id=1)`

Side note 2: you can see a representation of the SQL being generated for a queryset by printing the `.query` attribute of that queryset.

```auto
>>> ee = EventType.objects.get(event_type_id=1).event_set.all()
<QuerySet [<Event: Event object (2)>, <Event: Event object (3)>]>

```

If you then `print(ee.query)`, you’ll see the Django-internal representation of the SQL. (_Not_ the **real** SQL, but close enough for understanding.)

Final note, you wrote:

> [@swills1](#):
>
> But what would you use these for?

What is the “these” you are asking about? You’re touching on a number of different topics in your post and I’m unsure of the referent.

---

<div class="post-metadata">

**Author:** ![swills1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/swills1/32/6475_2.png) [@swills1](https://forum.djangoproject.com/u/swills1)\
**Post date:** [November 29, 2021, 3:06pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714/3 "2021-11-29T15:06:40Z")

</div>

Ken! You are the man! I was looking at this wrong and it was right in front of my face. I definitely need to re read what you wrote and try some things now.

You also hit on something I kept thinking myself,

> Side note 1: Personally, I am not a fan of this formulation.  
> (This being `EventType.objects.get(event_type_id=1).event_set.all()` ) It’s not obvious to me that what is being selected are Event objects and not EventType objects. I would typically recommend:  
> `Event.objects.filter(event_type_id=1)`

I actually wrote that to make a point - that some times it isn’t crystal clear what things to refer to using the ORM and that writing things a certain way make them more clear is important. It was also me “riffing” in the Shell to see what it could do, but I just kept adding onto it to see how bundled up I could make it.

After I re read and test, I’ll probably have another set of questions, but my main one right now is - So this returns an object. Which means I have all fields available to me. So I don’t necessarily have to do, `Event.objects.filter(event_type_id=1)`. I could actually filter where EventType’s event\_type = holiday as well, correct?

Thanks so much for the crystal clear explanation.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 29, 2021, 3:10pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714/4 "2021-11-29T15:10:56Z")

</div>

I think it would be more like `Event.objects.filter(event_type__event_type='holiday')`, but yea.

The first `event_type` in the filter is a reference to the field within `Event`.  
The double-underscores are the specification to follow that FK to the target object, in this case `EventType`.  
The second `event_type` then is the field reference within `EventType`.

(Syntactically, trying to specify something like `Event.objects.filter(event_type.event_type='holiday')` within Python would have a completely different meaning, and so Django uses the double-underscore notation to work around that.)

---

<div class="post-metadata">

**Author:** ![swills1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/swills1/32/6475_2.png) [@swills1](https://forum.djangoproject.com/u/swills1)\
**Post date:** [November 29, 2021, 3:22pm UTC](https://forum.djangoproject.com/t/could-anyone-please-explain-use-cases-for-relationships-between-models-when-using-fks/10714/5 "2021-11-29T15:22:58Z")

</div>

Thanks again. I’m definitely going to test around tonight.
