【问题标题】:Django: AttributeError - Object has no attributeDjango:AttributeError - 对象没有属性
【发布时间】:2011-01-24 00:13:29
【问题描述】:

这个视图抛出 AttributeError 说:'PhotoForm' 对象没有属性 'reservation'。会发生什么 - 函数通过,但实际上并没有上传图像。在调试它时,表单无效。

我试过打印

  • form.reservation
  • form.message
  • form.photo

但这显示了此回溯(这就是表单无效且未完成功能的原因。

当我根据其他正在运行的功能构建它时,我有点困惑。感谢您的帮助!

HTML 表单

<form action="/photo/new/" method="post">{% csrf_token %}
    <dl>
        <dt>{{ form.reservation.label }}</dt>
            <dd><select name="reservation"> {% for reservation in reservations %} <option value="{{reservation.id}}">{{reservation.date}} {{reservation.chef.cook.get_profile.firstname}} - {{reservation.guest.get_profile.firstname}}</option>{% endfor %}</select></dd>
        <dt>{{ form.photo.label }}</dt>
            <dd>{{ form.photo }}</dd>
        <dt> {{ form.message.label }}</dt>
            <dd>{{ form.message }}</dd>
    </dl>
<button type="submit">Submit</button>
</form>

观点

@login_required
def new_photo(request, template_name="photo/newphoto.html"):

  meals = Reservation.objects.filter(guest=request.user.id)
  form = PhotoForm(request.POST)
  form.data = { "reservations": meals }
  if request.method == 'POST':
    form.photographer = request.user
    form.data.get('reservation')
    print form.reservation
    print form.message
    print form.photo
    if form.is_valid():
      print" hellos"
      save_reservation_photo(request.FILES["photo"])
      photo = form.save(commit=False)
      photo.photographer = request.user
      photo.save()
      return HttpResponseRedirect('/photo/%d/' % photo.id )
  else:
    form = PhotoForm()

  data = {'form':form,'reservations':meals,
    'add':True
  }

  return render_to_response(template_name,
                            data,
                            context_instance=RequestContext(request))

表格:

class PhotoForm(forms.ModelForm):
  class Meta:
    model = Photo
    fields = ('reservation','photo','message')

  def __init__(self, *args, **kwargs):
      super(PhotoForm, self).__init__(*args, **kwargs)

模特:

class Photo(models.Model):

  photographer = models.ForeignKey(User)
  pub_date = models.DateTimeField(default=datetime.now,auto_now_add=True,db_index=True)
  reservation = models.ForeignKey(Reservation)

  message = models.CharField(default='',max_length=140)

  photo = models.ImageField(default='',upload_to="reservation_images/")

追溯

Traceback:
Environment:

Request Method: POST
Request URL: http://127.0.0.1:8000/photo/new/
Django Version: 1.2.3
Python Version: 2.7.0
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.comments',
 'django.contrib.markup',
 'django.contrib.sitemaps',
 'lib.debug_toolbar',
 'src',
 'django.contrib.admin']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'lib.debug_toolbar.middleware.DebugToolbarMiddleware')


Traceback:

Environment:

Request Method: POST
Request URL: http://127.0.0.1:8000/photo/new/
Django Version: 1.2.3
Python Version: 2.7.0
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.comments',
 'django.contrib.markup',
 'django.contrib.sitemaps',
 'lib.debug_toolbar',
 'src',
 'django.contrib.admin']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'lib.debug_toolbar.middleware.DebugToolbarMiddleware')


Traceback:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  25.                 return view_func(request, *args, **kwargs)
File "/Users/emilepetrone/Sites/meal/../meal/src/views.py" in new_photo
  532.     print form.reservation

Exception Type: AttributeError at /photo/new/
Exception Value: 'PhotoForm' object has no attribute 'reservation'

【问题讨论】:

  • 你能发布回溯吗?顺便说一句:你不需要设置 PhotoForm init 因为如果 PhotoForm 没有设置任何构造函数,那么基类构造函数将被调用
  • 在添加预订列后是否进行了同步数据库(或者从一开始就在其中)?
  • 异常来自print form.reservation 的行,这不在您发布的代码中。请发布显示问题的实际代码。
  • 我更新了视图/回调以显示打印语句。没有这些,表单无效并传递给 "else: form= PhotoForm()" 。所以问题是为什么表格无效?

标签: python django django-forms django-views


【解决方案1】:

不应该形成(带有图像或文件字段)be initialized with request.FILES

form = PhotoForm(request.POST, request.FILES)

【讨论】:

  • 嗯,我不确定,但试过了,并没有解决问题:/
【解决方案2】:

关键在于表单中有 files=request.FILES。

@login_required
def new_photo(request, template_name="photo/newphoto.html"):

  form = PhotoForm( user= request.user, data=request.POST, files=request.FILES)

  if request.method == 'POST':
    form.photographer = request.user
    if form.is_valid():
      photo = form.save(commit=False)
      photo.photographer = request.user
      photo.save()
      return HttpResponseRedirect('/photo/%d/' % photo.id )

【讨论】:

  • 虽然它是一个旧帖子,但你解决问题的方式有点奇怪。当您执行form = PhotoForm(...) 时,您已经在其中使用request.POST,然后您再次检查request.method='POST'
【解决方案3】:

您的入站表单处理在我看来有点奇怪,但我通常不使用 ModelForm。这是我的一般情况:

def some_form_view(request): 
  if request.method != 'POST': 
    raise Http404  # or whatever 
  form_data = FormClass(request.POST, request.FILES)
  if not form_data.is_valid():
    context['form'] = form_data 
    return render_to_response(...)  # invalid for m

  new_object = ModelObject(
      field=form_data.cleaned_data['field'], 
      other_field=form_data.cleaned_data['other_field'])
  new_object.save()

  context['new_object'] = new_object
  return render_to_response(...)  # success 

注意事项:

  • 我不认为“form.reservation”是一个有效的标识符。您应该只说“打印表单”或“打印 str(form)”,而不是尝试打印各个字段。

  • 几乎可以肯定,在对这些数据进行任何操作之前,您应该调用 is_valid()。如果表单本身无效,那应该/将引发表单验证错误。

  • 只能通过 form.cleaned_data['foo'] 直接访问表单数据,而不是通过 .data,因为您正在访问来自用户的潜在危险内容。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-01-09
    • 2023-03-03
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2021-03-30
    相关资源
    最近更新 更多