On Sun, 2007-10-28 at 01:15 +0000, Hani wrote:
> Hi,
> A complete and utter newbie seeks help.
> 
> I have a model Beer with another model called TastingNotes tied via
> foreign key to the Beer table.
> 
> 
> models.py
> 
> class Beer(models.Model):
>       beer=models.CharField(max_length=50, core=True)
>       def __unicode__(self):
>               return self.beer
> 
> 
> class TastingNote(models.Model):
>       beer=models.ForeignKey(Beer, edit_inline=models.TABULAR,
> raw_id_admin=True, num_in_admin=1)
>       tastingnotes=models.TextField('Tasting notes', core=True)
>       rating=models.CharField(max_length=1,
> choices=RATING_CHOICES,core=True)
> 
>       def __unicode__(self):
>               return self.tastingnotes[:15]+"... Rating:"+self.rating
> 
> (note that RATING_CHOICES is defined at the top of models.py).
> 
> What I would like is to have a field, average_rating, that belongs to
> the Beer model that is the average rating for that beer derived from
> all the ratings in the TastingNote model. So I could call it like
> this: beer.id.average_rating.
> 
> Would I do that with a manager class?

A manager class is usually only necessary if you need a method that
operates on *all* of the instances of this model. So, for example, if
you wanted some function that operated on all the Beers, it would be an
appropriate choice for a manager method on the Beer class.

In this case, though, you have a specific beer that is the centre of
attention, so just put a method on the Beer model. If you wrote
something like this:

        def average_rating(self):
            ratings = [o.rating for o in self.tastingnote_set.all()]
            return sum(ratings) / len(ratings)
        
as a method of the Beer model, it would do what you want. Then you could
call it as beer.average_rating() in Python code or beer.average_rating
in a template.

[Except there's a problem here: You've defined the "rating" field on
TastingNote to be a CharField, so "average" doesn't make a lot of sense.
Do you really want it to be an IntegerField? None of what I wrote in
that code will work for characters, because it assumes numerical
properties exist. sum() doesn't do anything for strings and division
certainly won't work.]

If you aren't familiar with Python, the first line above might be a
little confusing. Look up "list comprehensions" in the Python
documentation.

Also, from the sample code you wrote, it looks like you'll need to read
the Django documentation for how to use reverse relations. If you have
Beer instance and want to refer to all the TastingNote instances
associated with it, you would use

        my_beer.tastingnote_set.all()
        
like I did above (except that I had access to 'self' there, so that was
the thing I used, not my_beer). See [1] for details on this (that's a
link to deep in the middle of some documentation, so you might need to
scroll up the beginning of the section for it to make sense and try out
a few experiments).

[1] http://www.djangoproject.com/documentation/db-api/#backward

Regards,
Malcolm

-- 
Despite the cost of living, have you noticed how popular it remains? 
http://www.pointy-stick.com/blog/


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to