Re: rendering to template help
On May 27, 3:10 pm, Pirate Pete wrote: > hello again, > > i am trying to get a single entry from my db and then annotate the > count and rating to it like we established above > > however it doesn't seem to be returning anything: > videos = > Video.objects.get(id=vid_id).annotate(rating_count=Count('rating'), > rating_avg=Avg('rating__rating')) The trouble is that .get() directly returns an instance, not a queryset - so you can't call annotate() on it. It should work if you move the .get() clause to the end. > i even tried a filter: > > videos = > Video.objects.all().filter(id=vid_id).annotate(rating_count=Count('rating') , > rating_avg=Avg('rating__rating')) > > this is really puzzling me as to why it is not working. Any ideas? This should work, although remember that it will return a single-item queryset, rather than a single instance as above - so you'll still need to iterate through, or slice it (via videos[0]). > Also i seem to be getting an error with my |drawstars which works fine > on other pages that dont require this individual selection. > > I don't quite understand this error: > > "Caught an exception while rendering: a float is required" > > thanks in advance That's probably because you're passing the queryset, rather than individual instance, as I note above. You should be seeing error tracebacks, especially in the first example you show above - you should find they are helpful in debugging this sort of thing. -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
hello again, i am trying to get a single entry from my db and then annotate the count and rating to it like we established above however it doesn't seem to be returning anything: videos = Video.objects.get(id=vid_id).annotate(rating_count=Count('rating'), rating_avg=Avg('rating__rating')) i even tried a filter: videos = Video.objects.all().filter(id=vid_id).annotate(rating_count=Count('rating'), rating_avg=Avg('rating__rating')) this is really puzzling me as to why it is not working. Any ideas? Also i seem to be getting an error with my |drawstars which works fine on other pages that dont require this individual selection. I don't quite understand this error: "Caught an exception while rendering: a float is required" thanks in advance On May 25, 7:58 pm, Daniel Roseman wrote: > On May 25, 10:30 am, Pirate Pete wrote: > > > sorry for this one last question, > > > do you have any idea how i would go about rounding these values and > > converting them from numbers to *'s ? > > > i tried using the round() function on the annotation however it kept > > giving me a type error "a float is required." > > > cheers > > I'd probably do a customtemplatefilter: > > @register filter > def stars(value): > return '*' * int(round(value)) > > (you need both int and round, as int always rounds down, so you need > to do the rounding before converting to int). > > Then use it like this (after loading the library in thetemplate): > {{ video.rating_avg|stars }} > -- > DR. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group > athttp://groups.google.com/group/django-users?hl=en. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
On May 25, 10:30 am, Pirate Pete wrote: > sorry for this one last question, > > do you have any idea how i would go about rounding these values and > converting them from numbers to *'s ? > > i tried using the round() function on the annotation however it kept > giving me a type error "a float is required." > > cheers I'd probably do a custom template filter: @register filter def stars(value): return '*' * int(round(value)) (you need both int and round, as int always rounds down, so you need to do the rounding before converting to int). Then use it like this (after loading the library in the template): {{ video.rating_avg|stars }} -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
sorry for this one last question, do you have any idea how i would go about rounding these values and converting them from numbers to *'s ? i tried using the round() function on the annotation however it kept giving me a type error "a float is required." cheers On May 25, 7:10 pm, Daniel Roseman wrote: > On May 25, 9:52 am, Pirate Pete wrote: > > > Thank you very very much for your reply. > > > There is still a few things i need to grasp. > > > Firstly, why did you do this : > > annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rat > > ing')) > > as opposed to annotate(rating_count=Count('rating'), > > rating_avg=Avg('rating__rating')) > > No reason, these are equivalent. > > > Secondly, why is the average rating__rating and the count is only > > rating ? > > Because you're counting the individual rating objects, but you're > averaging the values of the 'rating' field on each rating object. > > > Unfortunately the code you provided doesn't seem to be working however > > that could just be my own ignorance at work. > > > Does this annotation need to be assigned to some sort of variable and > > passed into the render or just run like you stated above? > > Yes, sorry, assign it to the 'videos' variable and pass it straight > into the template context - you can delete the rest of the view code. > -- > DR. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group > athttp://groups.google.com/group/django-users?hl=en. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
You sir have saved me many a headache, i can't honestly thank you enough All the best! On May 25, 7:10 pm, Daniel Roseman wrote: > On May 25, 9:52 am, Pirate Pete wrote: > > > Thank you very very much for your reply. > > > There is still a few things i need to grasp. > > > Firstly, why did you do this : > > annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rat > > ing')) > > as opposed to annotate(rating_count=Count('rating'), > > rating_avg=Avg('rating__rating')) > > No reason, these are equivalent. > > > Secondly, why is the average rating__rating and the count is only > > rating ? > > Because you're counting the individual rating objects, but you're > averaging the values of the 'rating' field on each rating object. > > > Unfortunately the code you provided doesn't seem to be working however > > that could just be my own ignorance at work. > > > Does this annotation need to be assigned to some sort of variable and > > passed into the render or just run like you stated above? > > Yes, sorry, assign it to the 'videos' variable and pass it straight > into the template context - you can delete the rest of the view code. > -- > DR. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group > athttp://groups.google.com/group/django-users?hl=en. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
On May 25, 9:52 am, Pirate Pete wrote: > Thank you very very much for your reply. > > There is still a few things i need to grasp. > > Firstly, why did you do this : > annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rat > ing')) > as opposed to annotate(rating_count=Count('rating'), > rating_avg=Avg('rating__rating')) No reason, these are equivalent. > Secondly, why is the average rating__rating and the count is only > rating ? Because you're counting the individual rating objects, but you're averaging the values of the 'rating' field on each rating object. > Unfortunately the code you provided doesn't seem to be working however > that could just be my own ignorance at work. > > Does this annotation need to be assigned to some sort of variable and > passed into the render or just run like you stated above? Yes, sorry, assign it to the 'videos' variable and pass it straight into the template context - you can delete the rest of the view code. -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
Thank you very very much for your reply. There is still a few things i need to grasp. Firstly, why did you do this : annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rating')) as opposed to annotate(rating_count=Count('rating'), rating_avg=Avg('rating__rating')) Secondly, why is the average rating__rating and the count is only rating ? Unfortunately the code you provided doesn't seem to be working however that could just be my own ignorance at work. Does this annotation need to be assigned to some sort of variable and passed into the render or just run like you stated above? thanks again! On May 25, 6:08 pm, Daniel Roseman wrote: > On May 25, 6:09 am, Pirate Pete wrote: > > > > > I have been trying to get some kind of kind response from django for a > > few days now and it has been very unkind to me :P > > > basically i need to create a page that has a video title (link) and an > > average rating with the amount of people that rated it in brackets. > > > so it will look like ... Awesom video 5(3) : where awesom video is > > the name 5 is the average rating and 3 people have rated the video. > > > i can display the videos easily by using a for loop in the template > > however i am having much difficulty displaying the average ratings and > > count > > > rating model: > > > class RatingManager(models.Manager): > > def average_rating(self,video): > > avg = > > Rating.objects.filter(id=video.id).aggregate(Avg('rating')) > > return avg > > > def vote_count(self,video): > > num = > > Rating.objects.filter(id=video.id).aggregate(Count('rating')) > > return num > > > class Rating(models.Model): > > user = models.ForeignKey(User, unique=False) > > vid = models.ForeignKey(Video, unique=False) > > rating = models.PositiveIntegerField(help_text="User rating of the > > video.") > > objects = RatingManager() > > > def __str__(self): > > return str(self.user) + "'s rating: " + str(self.vid) > > > View: > > > def index(request): > > videos = Video.objects.all() > > dict= [] > > for vid in videos: > > ratec = > > (Rating.objects.vote_count(vid),Rating.objects.average_rating(vid)) > > dict.append(ratec) > > > return render_to_response("index.html", > > {'videos':videos,'ratecount':dict}) > > > index.html: (please note ratecount is just trial and error this could > > potentially be by all means completely incorrect) > > > TitleAverage Rating (Vote Count) > > {% for video in videos %} > > {{video.title}} > td>{{ratecount.0.1}}({{ratecount.0.0}}) > > {% endfor %} > > > thanks in advance > > Firstly, please don't call a variable 'dict' - it shadows Python's > built-in dict type. Especially not if the variable is actually a list, > not a dict. > > Secondly, you're just showing the same rate count - the first one - on > each and every video. I'm sure this isn't what you want. > > I think what you actually want to do here is to annotate the count and > avg on the video, not calculate separate aggregations for each one. > You can do this directly in the view, something like: > > Video.objects.all().annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rating')) > > Then in the template you can just do: > > {% for video in videos %} > {{video.title}} td>{{video.rating_avg}}({{video.rating_count}}) > {% endfor %} > > -- > DR. > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-us...@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group > athttp://groups.google.com/group/django-users?hl=en. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: rendering to template help
On May 25, 6:09 am, Pirate Pete wrote: > I have been trying to get some kind of kind response from django for a > few days now and it has been very unkind to me :P > > basically i need to create a page that has a video title (link) and an > average rating with the amount of people that rated it in brackets. > > so it will look like ... Awesom video 5(3) : where awesom video is > the name 5 is the average rating and 3 people have rated the video. > > i can display the videos easily by using a for loop in the template > however i am having much difficulty displaying the average ratings and > count > > rating model: > > class RatingManager(models.Manager): > def average_rating(self,video): > avg = > Rating.objects.filter(id=video.id).aggregate(Avg('rating')) > return avg > > def vote_count(self,video): > num = > Rating.objects.filter(id=video.id).aggregate(Count('rating')) > return num > > class Rating(models.Model): > user = models.ForeignKey(User, unique=False) > vid = models.ForeignKey(Video, unique=False) > rating = models.PositiveIntegerField(help_text="User rating of the > video.") > objects = RatingManager() > > def __str__(self): > return str(self.user) + "'s rating: " + str(self.vid) > > View: > > def index(request): > videos = Video.objects.all() > dict= [] > for vid in videos: > ratec = > (Rating.objects.vote_count(vid),Rating.objects.average_rating(vid)) > dict.append(ratec) > > return render_to_response("index.html", > {'videos':videos,'ratecount':dict}) > > index.html: (please note ratecount is just trial and error this could > potentially be by all means completely incorrect) > > TitleAverage Rating (Vote Count) > {% for video in videos %} > {{video.title}} td>{{ratecount.0.1}}({{ratecount.0.0}}) > {% endfor %} > > thanks in advance > Firstly, please don't call a variable 'dict' - it shadows Python's built-in dict type. Especially not if the variable is actually a list, not a dict. Secondly, you're just showing the same rate count - the first one - on each and every video. I'm sure this isn't what you want. I think what you actually want to do here is to annotate the count and avg on the video, not calculate separate aggregations for each one. You can do this directly in the view, something like: Video.objects.all().annotate(rating_count=Count('rating')).annotate(rating_avg=Avg('rating__rating')) Then in the template you can just do: {% for video in videos %} {{video.title}}{{video.rating_avg}}({{video.rating_count}}) {% endfor %} -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
rendering to template help
I have been trying to get some kind of kind response from django for a few days now and it has been very unkind to me :P basically i need to create a page that has a video title (link) and an average rating with the amount of people that rated it in brackets. so it will look like ... Awesom video 5(3) : where awesom video is the name 5 is the average rating and 3 people have rated the video. i can display the videos easily by using a for loop in the template however i am having much difficulty displaying the average ratings and count rating model: class RatingManager(models.Manager): def average_rating(self,video): avg = Rating.objects.filter(id=video.id).aggregate(Avg('rating')) return avg def vote_count(self,video): num = Rating.objects.filter(id=video.id).aggregate(Count('rating')) return num class Rating(models.Model): user = models.ForeignKey(User, unique=False) vid = models.ForeignKey(Video, unique=False) rating = models.PositiveIntegerField(help_text="User rating of the video.") objects = RatingManager() def __str__(self): return str(self.user) + "'s rating: " + str(self.vid) View: def index(request): videos = Video.objects.all() dict= [] for vid in videos: ratec = (Rating.objects.vote_count(vid),Rating.objects.average_rating(vid)) dict.append(ratec) return render_to_response("index.html", {'videos':videos,'ratecount':dict}) index.html: (please note ratecount is just trial and error this could potentially be by all means completely incorrect) TitleAverage Rating (Vote Count) {% for video in videos %} {{video.title}}{{ratecount.0.1}}({{ratecount.0.0}}) {% endfor %} thanks in advance -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.