2009-11-11 4 views
0

Я застрял в этой очень простой проблеме, но нигде не получил ее (новичок на Python и Django). Я беру некоторые данные, представленные пользователем, и используя весы для вычисления оценки. Несмотря на все мои усилия, я получаю следующее, когда я отправляю данные через форму: «глобальное имя« внешний вид »не определен». Я почти уверен, что моя проблема в views.py, но я не уверен на 100%. Либо ошибка при отображении, либо просто вычисление счета не в том месте. Буду признателен за любую оказанную помощь. Вот мой код:Пользовательский метод сохранения, дающий неверную ошибку размера кортежа

Update: Ошибка я получаю после изменения моего подхода к использованию пользовательского метода сохранения является:. «Неверный размер кортежа в создании Decimal из списка или кортежа список или кортеж должен иметь точно три элемента ".

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) 

ответ

0

В вашем методе экономии, линии:

scoredappearance = self.appearance * APPEARANCE_WEIGHT, 
... 

все назначения кортеж, а не номер вы ожидаете, к переменным. A tuple - это в основном неизменный список. Тренировочная запятая на всех этих линиях делает их кортежи. Вы хотите:

scoredappearance = self.appearance * APPEARANCE_WEIGHT 
... 

Другие проблемы с сохранением функции. Во-первых, из-за вашего отступа, ваш супер получает только звонок, что означает, что вы никогда не сможете создать этот объект!

Во-вторых, я бы рекомендовал добавить список переменных arg в вашу функцию сохранения. Это означает, что если он вызван с параметрами, они прозрачно передаются на супер.

Вот переписана функция:

def save(self,*args,**kwargs): 
    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(*args,**kwargs) 

В качестве последней ноты - и, если вы уже сделали это, я извиняюсь - я бы очень рекомендовал работать через книгу, как Learning Python. Python - это простой язык, но он имеет некоторые тонкие функции (например, кортежи и списки переменных аргументов), которые могут вызвать проблемы, если вы их не понимаете.

+0

Да, я заметил отступ через несколько минут после публикации обновления. И спасибо за намек на Python. Я сделал несколько руководств, но, как вы можете судить, мои знания довольно ограничены. Вероятно, лучше всего отложить проект Django, пока я не смогу стать более гибким в Python. Лучше всего в перспективе я уверен! Есть ли способ дать как частичный кредит в SO? Ван Гейл указал мне в правильном направлении, и вы поможете мне сбросить это направление. Спасибо за помощь ребята! – kfordham281

1

Сообщение об ошибке должно конкретно сказать вам файл и номер строки ошибки, но ваша проблема заключается в этих двух строках в вашем views.py:

appearance = form.cleaned_data['appearance'], 
scoredappearance = appearance * APPEARANCE_WEIGHT, 

Вы предполагаете, что интерпретатор Python вычисляет значение для appearance, прежде чем использовать его в следующем аргументе ... что является неправильным допущением.

Определите appearance, прежде чем создавать экземпляр модели, и тогда ваш код должен работать (или хотя бы разбить другую ошибку).

+0

Было бы лучше создать собственный метод для модели для обработки этого расчета? – kfordham281

+0

Да, это хорошая идея ... тогда вы можете быть уверены, что вы определяете свои константы наподобие «APPEARANCE_WEIGHT» в одном месте, что является тем же самым местом, в котором выполняется вычисление. –

+0

Поэтому я решил переопределить метод сохранения по умолчанию, но у меня возникли проблемы с подключением всего этого. Любые идеи о том, что может происходить здесь? Я редактировал свой вопрос, чтобы включить новый код. – kfordham281

Смежные вопросы