2

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

will-hart
  • 3,742
  • 2
  • 38
  • 48
KevTuck
  • 113
  • 8

2 Answers2

5

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.

schacki
  • 9,401
  • 5
  • 29
  • 32
0

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

ephsmith
  • 398
  • 3
  • 12
Mp0int
  • 18,172
  • 15
  • 83
  • 114