beerandsmiles
beerandsmiles

Reputation: 154

Django Form Error: 'QueryDict' object has no attribute 'method' when POST assigned

I'm having trouble with a specific form that is not permitting me to post data to a function I've defined. I'm very confused as to why this is giving me errors because I use an almost identical form to do another action in the same website.

When I post this data, Django throws "'QueryDict' object has no attribute 'method'" even though I've assigned the method as POST. It renders the form just fine when it's not posting, it's only when I submit I have a problem.\

The error that Django throws points to this line in views: if request.method == "POST": this is the first line in the "cancel" function below.

Can anyone identify what I've done wrong here? I'm at a loss.

Here's the function in view.py:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from .apps.instant import orderlist, orderdetails, cancel
from .forms import cancelorder

def cancel(request):
    if request.method == "POST":
        form = cancel(request.POST or None)
        if form.is_valid():
            response = cancel(request.session['token'],form.cleaned_data['orderId'], form.cleaned_data['reason'])
            return render(request, 'instant/review.html', {'data':response})
        else:
            form = cancelorder()
            return render(request, 'instant/cancel.html', {'form':form})
    else:
        form = cancelorder()
        return render(request, 'instant/cancel.html', {'form':form})

here's the forms.py:

from django import forms

class cancelorder(forms.Form):
    orderId = forms.CharField(label='Order Id', max_length=5)
    reason = forms.CharField(label='reason', widget=forms.Textarea)

here's the template it's rendering (instant/cancel.html):

{% extends "main/header.html" %}
{% load widget_tweaks %}
{% block content %}
<div class = "row">
  <div class ="col-sm-3">
  </div>
  <div class ="col-sm-6">
    <div class="alert alert-danger alert-dismissible" role="alert">
      <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      <strong>Warning!</strong> When you cancel, the host gets an email notifiaction! Also, there are no confirmations. Only click cancel if you're sure!
    </div>
  </div>
</div>
<div class = "row">
  <div class ="col-sm-3">
  </div>
  <div class ="col-sm-6">
    <div class="well-lg" style="background-color:#efefef">
      <center>
      <h3> cancel an order</h3>
    </center><br>
      <!-- <h3>Login</h3> -->
      <form action="/instant/cancel/" method="POST" class="post-form">{% csrf_token %}
        <div class="form-group">
          <label for="login_email">Order Id</label>
          {{ form.orderId|add_class:"form-control"|attr:"placeholder:Enter numbers only"}}
        </div>
        <div class="form-group">
          <label for="login_password">Reason</label>
          {{ form.reason|add_class:"form-control"|attr:"placeholder:Why are you cancelling?"}}
        </div>
        <button type="submit" class="btn btn-danger btn-lg">Send Cancellation</button>
      </form>
    </div>
  </div>
</div>
{% endblock %}

And finally here's the function that form collects data for. .apps.instant (I know the API I'm calling does function):

from time import sleep
import requests
import logging
import json

LOG_FILENAME = 'transaction_log.log' #Production Log
logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO,format='%(asctime)s %(message)s')

url = APIURL (removed for stackoverflow)

def cancel(token,orderId,reason):
    auth_token = {"Authorization" : "bearer " + str(token)}
    raw = {'instabookingId':orderId,"reason":reason}
    info = json.dumps(raw)
    cancellation = requests.post(url, headers=auth_token,data=info)
    response = cancellation.json()
    return response

I appreciate any help you can offer, really would like to know why this isn't working.

here's the error for Django:

Environment:


Request Method: POST
Request URL: http://164.132.48.154:8000/instant/cancel/

Django Version: 1.10.2
Python Version: 2.7.9
Installed Applications:
['main',
 'instant',
 'widget_tweaks',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/root/mysite/instant/views.py" in cancel
  24.         form = cancel(request.POST or None)

File "/root/mysite/instant/views.py" in cancel
  23.     if request.method == "POST":

Exception Type: AttributeError at /instant/cancel/
Exception Value: 'QueryDict' object has no attribute 'method'

Upvotes: 2

Views: 10994

Answers (2)

user15389622
user15389622

Reputation: 11

def cancel(request):
    if request.method == "POST":
        form = cancel(request.POST or None) # you call the function, its the same name, you would call your cancelform
        if form.is_valid():
            response = cancel(request.session['token'],form.cleaned_data['orderId'], form.cleaned_data['reason'])
            return render(request, 'instant/review.html', {'data':response})
        else:

In this, the function name in the views is cancel. Also, the form name that is mentioned in the 3rd line (cancel(request.POST or None)) is also cancel. That's the error.

Upvotes: 1

German Alzate
German Alzate

Reputation: 821

The error is in this line

...
def cancel(request):
    if request.method == "POST":
        form = cancel(request.POST or None) # you call the function, its the same name, you would call your cancelform
        if form.is_valid():
            response = cancel(request.session['token'],form.cleaned_data['orderId'], form.cleaned_data['reason'])
            return render(request, 'instant/review.html', {'data':response})
        else:
           ...

is recursively, the second time, in the function cancel, request == request.POST, and request.POST has not attribute 'method'

Upvotes: 1

Related Questions