Django What is reverse relationship?
Here is the documentation on related_name
Lets say you have 2 models
class Group(models.Model):
#some attributes
class Profile(models.Model):
group = models.ForeignKey(Group)
#more attributes
Now, from a profile object, you can do profile.group
. But if you want the profile objects given the group
object, How would you do that? Thats' where related name
or the reverse relationship
comes in.
Django, by defaults gives you a default related_name
which is the ModelName (in lowercase) followed by _set
- In this case, It would be profile_set
, so group.profile_set
.
However, you can override it by specifying a related_name
in the ForeignKey
field.
class Profile(models.Model):
group = models.ForeignKey(Group, related_name='profiles')
#more attributes
Now, you can access the foreign key as follows:
group.profiles.all()
Django | How to make a reverse Relationship with two models
Rather than using raw SQL joins, in Django you can traverse model relationships in either direction, regardless of how they are represented in the database.
To find all the messages for a given TicketSystem
instance:
my_ticket = TicketSystem.objects.get(id=0) # or something
my_ticket_messages = my_ticket.ticketsystem_messages_set.all() # or do other filters here
To find all the messages using a queryset
:
TicketSystem_Messages.objects.filter(ticketId=my_ticket)
To find all tickets with more than one message:
from django.db import Count
TicketSystem.objects.annotate(message_count=Count('ticketsystem_messagess')).filter(message_count__gt=1)
How do I write a Django ORM query for the reverse relationship in a one-to-many relationship?
The core issue here is the NameError
for articlestat
so I will address that first.
As explained in the django documentation your backward relation name by default is defined as FOO_set
which in your case means articlestat_set
.
If a model has a
ForeignKey
, instances of the foreign-key model
will have access to aManager
that returns all instances of the
first model. By default, thisManager
is named FOO_set,
where FOO is the source model name, lowercased.
If you prefer a different name you can do so by specifying a related_name
in your ForeignKey
definition e.g.
class ArticleStat(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='articlestats')
elapsed_time_in_seconds = models.IntegerField(default=0, null=False)
The second issue is how to properly follow relations which is explained quite extensively here which is why I will not go into detail about it in this answer. The gist is that instead of the .
operator you want to use __
(double underscore). The same goes for field lookups
which you need for comparison in this query.
With both these issues fixed your query should look like this:
Article.objects.filter(articlestat_set__elapsed_time_in_seconds__lte=300)
or with a custom related_name
e.g. related_name='articlestats'
:
Article.objects.filter(articlestats__elapsed_time_in_seconds__lte=300)
Reverse relation in Django
Django uses the related_name
of the foreign key to provide a reverse accessor - see the related objects documentation. In your FK from Post_image to Post you have (strangely) called your foreign key "post", therefore you access the images via post.post.all
.
Really you should give this a name that actually describe what it does: images
would be more suitable. Although you could just as well remove the explicit related_name completely, in which case Django will use the default, which in this case would be post_image_set
.
Django reverse relationship (with annotate and filtering)
annotate
the count on the Player
model and filter on the count:
from django.db.models import Count
Player.objects.filter(
age=25,
matchsup__match__in=matchlist
).annotate(
match_count=Count('matchsup')
).filter(match_count__lt=5)
How to call OneToOneField reverse relationship in template (django)?
As @khadim hussen wrote in the comment you should use the following syntax:
p.user.first_name
Where p
is your UserInfo
model and p.user
is the reference to the OneToOne realationship.
Note that when you don't have a related user with p -> user the value you will return is None
.
If you want to show different info than None
in your template just can do the following validation:
{% if p.user is not None %}
{{p.user}}
{% else %}
Without User
{% endif %}
But in your views yo will get a RelatedObjectDoesNotExists
to ensure in your views that the relationship exists you can make the following validation:
p = UserInfo.objects.first()
if hasattr(p, 'user'):
user = p.user
Other thing that is important is when you have a related_name property as in your example:
user = models.OneToOneField(User, related_name="parent_user", on_delete=models.CASCADE)
So in this case you need to refer to the user
property with the related_name
.
In a more concrete way you have to do as following:
{{ p.parent_user.first_name }}
One important thing is that if you ar using queryset.filter(...).values()
so if you want to load values from other model you can use the following:
queryset.filter(...).values('image','age','bio','user','parent_user__first_name',...)
``
And in your template:
```python
{% p.parent_user__first_name %}
That's it.
How to make reverse relationship query with count in Django
You can work with a .annotate()
[Django-doc] and then .filter(…)
[Django-doc]:
from django.db.models import Count
Product.objects.annotate(
noptions=Count('product_options')
).filter(
noptions__gt=0
)
Since django-3.2, you can also work with .alias(…)
[Django-doc]:
from django.db.models import Count
Product.objects.alias(
noptions=Count('product_options')
).filter(
noptions__gt=0
)
Related Topics
Recursive Definitions in Pandas
Split an Integer into Digits to Compute an Isbn Checksum
How to Print a Percentage Value in Python
Differencebetween Exec_Command and Send with Invoke_Shell() on Paramiko
Python Daemon and Systemd Service
Sending Mail from Python Using Smtp
How to Plot Normal Distribution
Text Box with Line Wrapping in Matplotlib
Pandas: Convert Dtype 'Object' to Int
Django Model Field Default Based Off Another Field in Same Model
Scaling of Tkinter Gui in 4K (3840*2160) Resolution
Creating Lowpass Filter in Scipy - Understanding Methods and Units
Converting Between Datetime and Pandas Timestamp Objects
How to Use Append with Pickle in Python
How to Create Collapsible Box in Pyqt
Find Element's Index in Pandas Series