KevTuck
KevTuck

Reputation: 113

Django Two Way relationship

I am building a blog site and have models in respect of Category and Posts. Posts have a Many to Many relationship for Category.

class Post(models.Model):
     categories = models.ManyToManyField(Category)

Everything is working fine aside from the fact that in the Category list in the template I only want to load categories that actually have posts.

If a category is empty I don't want to display it, I have tried to define a relationship in Category to Post to allow me to use something like {{ if category.posts }}. At the moment using another Many to Many field in Category is presently giving me an extra field in admin which I don't really want or feel that's needed.

How is best to navigate this relationship, or create one that's suitable?

Cheers Kev

Upvotes: 2

Views: 2623

Answers (2)

Mp0int
Mp0int

Reputation: 18727

You can use reverse relations on ManyToMany fields. In the reverse filter, you must use the related model name (if you did not use related_name attribute). So in your question you can use model name as the reverse name like:

{% if category.post %}

You can also use this in your filtering functions in views:

Category.objects.filter(post__isnull=False)

Reverse relation name must be lowercase.

Check the documentation here

Upvotes: 0

schacki
schacki

Reputation: 9533

Django automatically creates a field on the related model of any ForeignKey or ManyToMany relationship. You can control the name of the field on the related model via the related_name option like that:

class Post(models.Model):
 categories = models.ManyToManyField(Category,related_name='posts')

This way, your approach works without any additional fields. Btw, if you leave out the related_name argument, Django will create by default one with [field_name]_set.

Upvotes: 5

Related Questions