I've been stuck on this likely very simple problem, but haven't gotten anywhere with it (newbie to Python and Django). I'm taking some user submitted data and using weights to calculate a score. Despite my best efforts, I'm getting the following when I submit the data via a form: "global name 'appearance' is not defined". I'm pretty sure my issue is in views.py, but I'm not 100% sure. Either a typecast error or just putting the calculation of the score in the wrong place. Any help is much appreciated. Here's my code:
Update: The error I'm receiving after changing my approach to using a custom save method is: "Invalid tuple size in creation of Decimal from list or tuple. The list or tuple should have exactly three elements.".
models.py
# Beer rating weights
APPEARANCE_WEIGHT = 0.15
AROMA_WEIGHT = 0.15
MOUTHFEEL_WEIGHT = 0.10
TASTE_WEIGHT = 0.25
TOTALPACKAGE_WEIGHT = 0.25
SERVING_TYPE = (
('0', 'Choose One'),
('Draft', 'Draft'),
('Bottle', 'Bottle'),
('Can', 'Can'),
)
SCORING = (
(0, ''),
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
(6, '6'),
(7, '7'),
(8, '8'),
(9, '9'),
(10, '10'),
)
class Beerrating(models.Model):
beerrated = models.ForeignKey(Beer)
user = models.ForeignKey(User)
date = models.DateTimeField(auto_now_add=True)
servingtype = models.CharField(max_length=10, choices=SERVING_TYPE)
appearance = models.IntegerField(choices=SCORING, default=0)
aroma = models.IntegerField(choices=SCORING, default=0)
mouthfeel = models.IntegerField(choices=SCORING, default=0)
taste = models.IntegerField(choices=SCORING, default=0)
totalpackage = models.IntegerField(choices=SCORING, default=0)
comments = models.TextField()
overallrating = models.DecimalField(max_digits=4, decimal_places=2)
def __unicode__(self):
return u'%s, %s' % (self.user.username, self.beerrated.beername)
def save(self):
if not self.id:
scoredappearance = self.appearance * APPEARANCE_WEIGHT,
scoredaroma = self.aroma * AROMA_WEIGHT,
scoredmouthfeel = self.mouthfeel * MOUTHFEEL_WEIGHT,
scoredtaste = self.taste * TASTE_WEIGHT,
scoredtotalpackage = self.totalpackage * TOTALPACKAGE_WEIGHT,
self.overallrating = (scoredappearance + scoredaroma +
scoredmouthfeel + scoredtaste + scoredtotalpackage)
super(Beerrating, self).save()
forms.py
class BeerReviewForm(ModelForm):
servingtype = forms.CharField(max_length=10,
label=u'Serving Type',
widget=forms.Select(choices=SERVING_TYPE)
)
totalpackage = forms.IntegerField(
label=u'Total Package',
widget=forms.Select(choices=SCORING)
)
class Meta:
model = Beerrating
exclude = ('beerrated', 'user', 'date', 'overallrating')
views.py
def beerreview(request, beer_id):
beer = get_object_or_404(Beer, id=beer_id)
if request.method == 'POST':
form = BeerReviewForm(request.POST)
if form.is_valid():
# Create review
beerrating = Beerrating(
beerrated = beer,
user = request.user,
servingtype = form.cleaned_data['servingtype'],
appearance = form.cleaned_data['appearance'],
scoredappearance = appearance * APPEARANCE_WEIGHT,
aroma = form.cleaned_data['aroma'],
scoredaroma = aroma * AROMA_WEIGHT,
mouthfeel = form.cleaned_data['mouthfeel'],
scoredmouthfeel = mouthfeel * MOUTHFEEL_WEIGHT,
taste = form.cleaned_data['taste'],
scoredtaste = taste * TASTE_WEIGHT,
totalpackage = form.cleaned_data['totalpackage'],
scoredtotalpackage = totalpackage * TOTALPACKAGE_WEIGHT,
comments = form.cleaned_data['comments'],
)
beerrating.save()
return HttpResponseRedirect('/beers/')
else:
form = BeerReviewForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('beer_review.html', variables)