1

This view is throwing the AttributeError saying :'PhotoForm' object has no attribute 'reservation'. What happens- the function passes, but doesn't actually upload the image. In debugging it, the form is not valid.

I tried printing

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

But that shows this traceback ( which is the reason why the form isn't valid & not completing the function.

As I built this off other functions that are working, I'm a bit confused. Thanks for the help!

The HTML Form

<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>

The View

@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))

The Form:

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

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

The Model:

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/")

The traceback

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'
4
  • can you post traceback? btw: you dont need to set PhotoForm init because if PhotoForm dont set any constructor then base class constructor will be called Commented Jan 24, 2011 at 0:18
  • Did you do a syncdb after adding in the reservation column (or was it in there from the get-go)? Commented Jan 24, 2011 at 0:39
  • 2
    The exception is coming from a line with print form.reservation, which isn't in the code you've posted. Please post the actual code showing the problem. Commented Jan 24, 2011 at 7:14
  • I updated the view/call back to show the print statements. Without those, the form is not valid and passes to the "else: form= PhotoForm()" . So the question is why isn't the form valid ? Commented Jan 24, 2011 at 13:37

3 Answers 3

5

should not forms (with image or file fields) be initialized with request.FILES?

form = PhotoForm(request.POST, request.FILES)
Sign up to request clarification or add additional context in comments.

1 Comment

Hmm I'm not sure, but tried it and it didn't solve the problem :/
4

The key was having files=request.FILES in the form.

@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 )

1 Comment

although its an old post, but your way of solving the problem is a bit odd. When you are doing form = PhotoForm(...) you are already using request.POST in that and then again you are checking that request.method='POST'
0

Your inbound form processing looks a bit odd to me, but I usually don't use ModelForm. Here's what mine generally look like:

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 

So things to note:

  • I don't think "form.reservation" is a valid identifier. You should just say "print form" or "print str(form)" and not try to print the individual fields.

  • You should almost certainly be calling is_valid() before doing anything with that data. That should/will raise the form validation errors if the form itself is invalid.

  • Only ever access the form data directly through form.cleaned_data['foo'] and never via .data, because you're accessing something potentially dangerous coming in from the user.

Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.