Django'NonType'对象没有使用表单保存属性'__getitem__'

时间:2014-01-17 12:11:02

标签: python django django-forms

我有一个相当简单的表单,但是我收到了一个带有ModelChoiceField的TypeError,我无法理解为什么。表单返回模型ID号,并且使用该号码我应该能够查找特定模型并将其用于任何目的。虽然这不是那样的。这是我的表格代码:

class TestimonialForm(forms.Form):
    title = forms.CharField(max_length=100)
    content = forms.CharField(max_length=500, widget=forms.Textarea)
    ratings = (
        (1, '1'),
        (2, '2'),
        (3, '3'),
        (4, '4'),
        (5, '5')
          )
    rating = forms.ChoiceField(choices=ratings, widget=forms.RadioSelect)
    reward = forms.ModelChoiceField(queryset=Reward.objects.all())
    username = forms.CharField(max_length=50, widget=forms.HiddenInput)
    def clean(self):
        cleaned_data = super(TestimonialForm, self).clean()
        usr = cleaned_data.get('username')
        res = cleaned_data.get('reward')
    if Reward_Review.objects.filter(id=res.id).filter(affiliate__username=usr):
        raise forms.ValidationError("You have already submitted a testimonial. You can only submit one per gift card.")
    if not Redeem.objects.filter(reward__id=res.id).filter(affiliate__username=usr):
        raise forms.ValidationError("You haven't received this gift card yet, so you cannot write a review for it.")
    def clean_username(self):
    data = self.cleaned_data['username']
    try: 
        Affiliate.objects.get(user__username=data)
    except ObjectDoesNotExist, e:
        msg = 'The username provided by the form submission does not match anyone in our database.'
        logger.exception(e)
        logger.debug(msg, exc_info=True)
        raise forms.ValidationError("Invalid username. Please try again later.")
    return data
    def save(self, request, *args, **kwargs):
    data = self.cleaned_data
    user = request.user
    re = Reward.objects.get(id=data['reward'])
    points = Points.objects.create(affiliate=user, points=float(10), from_offer=False, from_task=True)
    rate = Reward_Rating.objects.create(affiliate=user, reward=re, rating_value=data['rating'])
    testimonial = Reward_Review.objects.create(affiliate=user, reward=re, reward_rating=rate, review_title=data['title'], review_content=data['content'])
    return testimonial

完整追踪:

Environment:
Request Method: POST
Traceback:

File "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  29.             return bound_func(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  25.                 return func(self, *args2, **kwargs2)
File "/app/myapp/views.py" in dispatch
  756.         return super(TestimonialFormView, self).dispatch(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/newrelic-2.8.0.7/newrelic/hooks/framework_django.py" in wrapper
  809.             return wrapped(*args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  87.         return handler(request, *args, **kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/django/views/generic/edit.py" in post
  171.             return self.form_valid(form)
File "/app/myapp/views.py" in form_valid
  743.  form.save(self.request)
File "/app/myapp/forms.py" in save
  215.  re = Reward.objects.get(id=data['reward'])

Exception Type: TypeError at /testimonials/
Exception Value: 'NoneType' object has no attribute '__getitem__'

3 个答案:

答案 0 :(得分:2)

django-1.6 Form源代码中的

Somewhere有一行:

self.cleaned_data = self.clean()

这意味着您应该使用clean方法返回字典。

这样的事情:

def clean(self, ...):
    // whatever
    return cleaned_data

注意:在django的未来版本中不需要从clean方法返回字典:

  

在Django开发版中更改:在以前版本的Django中,   form.clean()需要返回cleaning_data的字典。这个   方法仍然可以返回要使用的数据字典,但它不是   需要更长时间。

答案 1 :(得分:1)

Form.clean() 必须返回已清理的数据。

答案 2 :(得分:0)

Probaby问题就在这里

 re = Reward.objects.get(id=data['reward'])

使用ModelChoiceField时,您的cleaned_data词典已经包含相应的对象(而不是id) - 所以只需

re = data['reward']