djangodjango-modelsdjango-viewsdjango-templatesrating

How display Average Ratings on several pages in Django


Am trying to display the Average ratings on other pages in Django, but it fails. Below its my code.

models.py

class ActionGame(models.Model):
    
    publication_status = models.CharField(max_length=20, choices=STATUS, default="Draft")
    cid =ShortUUIDField(help_text='Place for the Game ID ', unique=True, max_length=10, length=7, prefix='act',alphabet='abcdfgh12345' )
    game_name = models.CharField(max_length=50, help_text='Enter The Name Of Game')
    game_image = models.ImageField(help_text='Enter The Game Picture Here',default='Action-images/default.jpg',upload_to='Action-images')

RATING=[
    (1,"★"),
    (2,"★★"),
    (3,"★★★"),
    (4,"★★★★"),
    (5,"★★★★★"),
]
class ActionGameReview(models.Model):
    game_name =models.ForeignKey(ActionGame, on_delete=models.CASCADE, related_name='reviews')
    user =models.ForeignKey(User, on_delete=models.CASCADE)
    review =models.TextField(max_length=5000, blank=False)
    rating = models.IntegerField(default=1, choices=RATING)
    created_at=models.DateTimeField(auto_now_add=True)

Views.py

def action_description(request, cid):
    description=ActionGame.objects.get(cid=cid)
    #getting Average Review
    avg_rating=ActionGameReview.objects.filter(game_name=ActionGame.objects.get(cid=cid)).aggregate(rating=Avg('rating'))
    # ......


def action(request):
    action_pages = ActionGame.published.all()
    # .....

This is my template for Action View

  {% for action_game in action_games %}
  
  <div class="col-md-6 themed-grid-col title-4-1 mt-5">
    <div class="row">
      <div class="col-md-7 themed-grid-col title-4-1-1  "> <img src="{{action_game.game_image.url }}" alt="" srcset=""></div>
      <div class="col-md-5 themed-grid-col title-4-1-2 ">
        <a href="{{ action_game.get_absolute_url }}"><b>{{ action_game.game_name }}</b></a> <br>
        <a href="https://{{action_game.official_site}}"><strong class="dev">{{action_game.developer}}</strong> </a><br>

<!----===== this is section for the Average Ratings of each game====---->
       
        <b>{{ action_rating }}</b> <br>
<!--===========================================================-->

        <p>
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16">
            <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
            <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
          </svg>
          &nbsp; 250.4K
        </p>  
        <a href="{{ action_game.get_absolute_url }}"><button class="btn btn-outline-success">Download</button></a>
      </div>
    </div>
  </div>
 
  {% endfor %}

The issue is, l cant display the ratings average in the action view template yet on the action-description Works veryfine.

how can l imprement the Average Rating on other pages, Anyone to help me.


Solution

  • You need to use annotate to count a rating for each ActionGame object:

    from django.db.models import Avg
    
    action_pages = ActionGame.published.annotate(rating=Avg('reviews__rating'))
    

    And then you can access it using rating attribute:

    action_pages[0].rating
    

    UPD: In your template access the rating:

    {% for action_game in action_games %}
        ...
    
        <b>{{ action_game.rating }}</b> <br>
    
        ...
    {% endfor %}