Django Responds code 500 no matter what - python

I have a method in Django where I get POST data from a mobile app and all I do is save it and send a Response. The problem is though the the data gets saved but no matter what the app receives the response code 500.
<Response [500]>
code:
#csrf_exempt
def store_recordings(request):
if request.method == 'POST':
print "In POST",request.POST
driverName = request.POST['driverName']
driverMobileNum = request.POST['driverMobileNum']
customerMobileNum = request.POST['customerMobileNum']
salesOrderNo = request.POST['salesOrderNo']
callRecord = request.POST['callRecord']
latitude = request.POST['latitude']
longitude = request.POST['longitude']
callStart = request.POST['callStart']
callEnd = request.POST['callEnd']
callDuration = request.POST['callDuration']
callType = request.POST['callType']
driverrecording = DriverRecording(driverName=driverName,driverMobileNum=driverMobileNum,customerMobileNum=customerMobileNum,salesOrderNo=salesOrderNo,callRecord=callRecord,latitude=latitude,longitude=longitude,callStart=callStart,callEnd=callEnd,callDuration=callDuration,callType=callType)
save_or_not = driverrecording.save()
driverexist = DriverNames.objects.all()
new_driver_flag = False
driverName_list = [each.driverName for each in driverexist]
driverName_list = list(set(driverName_list))
if driverName in driverName_list:
pass
else:
DriverNames(driverName=driverName,driverMobileNum=driverMobileNum).save()
return HttpResponse(status=201)
else:
return HttpResponse(status=400)
I am perplexed what is the problem.
Thanks.

Almost certainly, one or more of those fields is not being sent, so you are getting a KeyError. If you set DEBUG to True you would see the traceback.
You should be using Django's forms framework, instead of directly accessing the POST data. That will validate the input and allow you to display any errors.

Related

get parameters in a get request in django rest framework?

I want to get the parameters sent to my rest api
what I want is to obtain the parameters that to use them consume another api and return the response of the third party api
but in name and comic i get None
http://127.0.0.1:8000/searchComics/
{name:"3-D Man","comics":12}
this is my view
class MarvelApi(APIView):
def get(self, request):
private_key = "88958f2d87bd2c0c2fa07b7ea654bcdf9f0389b3"
public_key = "8d415ffcc9add56b0a47c0a7c851afc3"
ts = 1
md5_hash = "46ecbbd63108b0561b8778a57823bd34"
query_params = self.request.query_params
name = query_params.get('kword', None)
comic = query_params.get('comic', None)
end_point = f"https://gateway.marvel.com:443/v1/public/characters?ts={ts}&apikey={public_key}&hash={md5_hash}&name={name}&comic={comic}"
response = requests.get(end_point)
response_json = json.loads(response.text)
return Response(status=status.HTTP_200_OK, data=response_json)
I think the problem is these two lines
name = query_params.get('kword', None)
comic = query_params.get('comic', None)
that do not capture the values ​​correctly, do you know how to solve it?
You wanted to get them from GET method, but instead you gave a dictionary, so I guess you sent it via POST. Instead of posting dictionary you should go with url:
http://127.0.0.1:8000/searchComics/?name=3-D+Man&comic=12
And you had probably a typo. You had plural "comics" in dictionary and you seek for "comic" singular.
And if you want to have data with POST method, just change def get(...) to def post(...).

Django Redirect does not work at all within view

I am trying to get my view to redirect to another page after clicking a button that triggers the POST request. I cannot seem to figure out why the redirect doesn't work or why it doesn't even seem to try to redirect.
Here is my view:
def cart1(request):
if request.user.is_authenticated:
#POST
if request.method == "POST":
#JSON Data
data = request.body
new_data = ast.literal_eval(data.decode('utf-8'))
customer = request.user
user_order = Order(user=customer)
user_order.save()
x = 0
while x < len(new_data.keys()):
obj_title = new_data[x]["title"]
obj_price = new_data[x]["price"]
obj_quantity = new_data[x]["quantity"]
obj_extra = new_data[x]["extra"]
total = round(float(obj_price.replace("$", "")))
m = OrderItem(order=user_order, title=obj_title, price=total, quantity=obj_quantity, extra=obj_extra)
m.save()
x += 1
return redirect('checkout-page')
return render(request, 'cart.html')
Any help would be appreciated, thank you
redirect(…) [Django-doc] produces a HttpRedirectResponse, you need to return it, so:
return redirect('checkout-page')
redirect(…) itself thus does not stop the code flow to redirect return a HTTP redirect response, it constructs such response, and your view should then return that response.
you need to be sure the URL name =checkout-page is in the current app otherwise you need to make it redirect('app:checkout-page')
However,I suggest to use from django.http import HttpResponseRedirect

Variables getting refreshed with HTML POST operation in Flask

I am trying to build a simple numeric captcha for my contact page in Flask. The contact page end-point loads in GET mode and initializes the values of the captcha verification. When I submit the form in POST mode, I expect my user-entered form value to match the captcha value. However, it is not working as expected. I did some troubleshooting with print statements to see how the values are changing and it appears that the captcha variables are getting re-initialised with the POST operation. Can someone please suggest a workaround? My Python code is shared below:
#bp.route('/contact/', methods=('GET', 'POST'))
def contact():
# Initialize captcha values
cap_a = random.randint(0, 9)
cap_b = random.randint(0, 9)
cap_prod = cap_a * cap_b
print(cap_a, cap_b, cap_prod)
if request.method == "POST":
error = None
log_file = current_app.config['LOGFILE']
full_name = request.form['fullname']
email_addr = request.form['email']
phone_no = request.form['phone']
msg_body = request.form['message']
num_prod = request.form['verifycaptcha']
print(cap_a, cap_b, cap_prod)
print(full_name, email_addr, phone_no, msg_body, num_prod)
if not full_name:
error = 'Full name is required.'
elif not email_addr:
error = 'Email address is required.'
elif not msg_body:
error = 'Message body is required.'
if num_prod != cap_prod:
error = 'Incorrect captcha verification.'
if error is None:
# Perform some operations
pass
try:
with current_app.app_context():
mail = Mail()
mail.init_app(current_app)
mail.send(msg)
error = 'Mail sent successfully!'
except:
error = 'Mail engine error encountered. Please retry after some time.'
f = open(log_file, "a")
f.write('['+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+'] '+error+'\n')
f.close()
flash(error)
return render_template('contact.html',num_a = cap_a, num_b = cap_b)
cap_a = random.randint(0, 9)
cap_b = random.randint(0, 9)
cap_prod = cap_a * cap_b
these are 2 random numbers and you are creating cap_prod. You are not saving the cap_prod anywhere. You are instead calculating it again when POST request comes (this time it will be 2 new random numbers)
You need to save the captcha that you created during the GET, and then when the POST comes , compare with the value that was originally sent.
If you are going to support refresh-captcha image in the future (you need to have an API call that will generate a new captcha and save it)
I figured out the solution by storing the captcha variables in the session dictionary of Flask and checking for its existence before re-initialising the values.
def contact():
# Initialize captcha values
if 'product' not in session:
cap_a = random.randint(0, 9)
cap_b = random.randint(0, 9)
session['captcha_a'] = cap_a
session['captcha_b'] = cap_b
session['product'] = cap_a * cap_b
else:
cap_a = session.get('captcha_a')
cap_b = session.get('captcha_b')
if request.method == "POST":
pass
# Rest of the code
Working examples of the above solution can be found at Fadmeter.com and FadURL.com.

How do I make independent API's?

I'm far from being an expert on the topic and my question might even make no sense, but I'm trying to make an app that gathers data from a server I made. There's a Python script I made that logs into a website and scrapes data from it. When you make a GET request to the API, the Python functions get called and the data is put on a server for the app to take. Thing is: whenever a user makes a GET request (or even a POST request, to send the credentials needed for the Python script to log in), the server changes for every user. For example, if a user posts his credentials, the dictionary "credentials" is changed for everyone and if a second user posts his credentials at the same time, the dictionary might get the wrong values for one of the two users. Here's the code:
from flask import Flask, request, jsonify
import backend as b
app = Flask(__name__)
credentials = dict()
subjectNames = ['Italiano', 'Inglese', 'Filosofia', 'Storia', 'Matematica', 'Informatica', 'Fisica', 'Scienze', 'Arte', 'Educazione Fisica']
#app.route('/login', methods=['POST'])
def getCredentials():
if request.method == 'POST':
username = request.get_json(force=True).get('username')
password = request.get_json(force=True).get('password')
credentials['username'] = username
credentials['password'] = password
return jsonify({'credentials': credentials})
#app.route ('/creds', methods=['GET'])
def creds():
return jsonify({'credentials': credentials})
#app.route('/api', methods=['GET'])
def api():
if request.method == 'GET':
query = str(request.args['query'])
if query == 'marks':
d = {}
m = b.getFullMarks(b.login(credentials['username'], credentials['password']))
for i in range(len(subjectNames)):
d[subjectNames[i]] = m[i]
return jsonify(d)
elif query == 'names':
d = {}
m = b.getNames(b.login(credentials['username'], credentials['password']))
for i in range(len(subjectNames)):
d[subjectNames[i]] = m[i]
return jsonify(d)
elif query == 'calendar':
d = {}
m = b.calendar(b.login(credentials['username'], credentials['password']))
d['Calendar'] = m
return jsonify(d)
elif query == 'badge':
d = {}
m = b.badge(b.login(credentials['username'], credentials['password']))
d['Badge'] = m
return jsonify(d)
if __name__ == '__main__':
app.run()
Leaving aside the fact that you keep all of the credentials in memory, and if the server crashes, you lost everything.
You can't use a dictionary to do as you want, as you already know, a dictionary can only hold a single representation of the same key (in our case, 'username'). so when a 2nd user calls the /login endpoint, you're overwriting the previous one and vice versa.
As mentioned before, most applications will generate a token on a successful login, and will send it back to the calling user.
The user will add it as a header on his upcoming requests, this allows the service to identify the calling user, and do whatever it needs.
You can look for existing implementations, or do something on your own.
but eventually, you'll need to map the token to the user, e.g:
#app.route('/login', methods=['POST'])
def getCredentials():
if request.method == 'POST':
username = request.get_json(force=True).get('username')
password = request.get_json(force=True).get('password')
token = generate_token_for_user(username, password)
credentials[token] = {'username': username, 'password': password}
return jsonify({'token': token})
and in the api call:
#app.route('/api', methods=['GET'])
def api():
token = request.headers['Authorization'] # assuming you're using this for your token
creds = credentials.get(token)
d = {}
if request.method == 'GET':
query = str(request.args['query'])
if query == 'marks':
m = b.getFullMarks(b.login(creds['username'], creds['password']))
for i in range(len(subjectNames)):
d[subjectNames[i]] = m[i]
return jsonify(d)
elif query == 'names':
m = b.getNames(b.login(creds['username'], creds['password']))
for i in range(len(subjectNames)):
d[subjectNames[i]] = m[i]
return jsonify(d)
elif query == 'calendar':
m = b.calendar(b.login(creds['username'], creds['password']))
d['Calendar'] = m
return jsonify(d)
elif query == 'badge':
m = b.badge(b.login(creds['username'], creds['password']))
d['Badge'] = m
return jsonify(d)
Offcourse, that maintaining a token lifecycle is a bit more complex, need to invalidate the token after a period of time, and you'll need to validate it on every request (usually with a middleware), but this is the concept.

Redirect url clashes with flask-;login

I currently have a flask server and an angular js front end on which users can buy things from third party vendors.
These third party vendors have their own payment gateways to which I connect my front end to... So at the point of making the payment, we redirect the user to the payment gateway... Once a payment is made, we have a redirect url on our flask servers that captures the success message (and the payment details).
The issue here is that since we do it on the front end (and since this is a third party's website), the flask-login does not seem to work. We use session to store some of the data of the purchase and thus, we cant seem to be able to connect the product the customer has bought with the transaction he made to buy it!
I have given my apis below:
#api.route('/quoteRequest/',methods = ['POST'])
# #flask_login.login_required
def carquote():
data = request.get_json()
c = quoteController.FUTGENGI(data = data, lob = "Motor", stage="quote")
d = c.finOutput
finalQuotes = []
finalQuotes.append(d)
return Response(json.dumps(finalQuotes),mimetype = "application/json")
#api.route("/proposalRequest/",methods = ['POST'])
def proposalRequest():
data = request.get_json()
current_app.logger.debug(data)
c = quoteController.FUTGENGI(data = data, lob = "Motor", stage="proposal")
output = json.loads(c.quoteDict)
session['proposal'][data['Quote']['insurerID']] = data
return Response(json.dumps(output),mimetype = "application/json")
#Redirect URL:
#api.route('/FUTGENGI/policyCreate/', methods = ['GET','POST'])
def policyCreate(insurerID):
if request.method == "GET":
par = OrderedDict(
WS_P_ID = request.args.get('TranID')
TID = request.args.get('UID')
PGID = request.args.get('PaymentID')
Premium = request.args.get('Amt')
Response = request.args.get('Response')
)
if(par['Response'] == "Success"):
for k,v in par.items():
session['proposal']['FUTGENGI'][k] = v
c = quoteController.FUTGENGI(data = session['proposal']['FUTGENGI'], lob = "Motor", stage="payment")
return Response(json.dumps(c.paymentOutput), mimetype = "application/json")
else:
return Response(json.dumps({"output":"Oops. Something went wrong. Please try again"}), mimetype = "application/json")

Categories