I am trying to get the POST data parameters in the exact order they are received in Django.
I have this in my views.py:
#require_POST
#csrf_exempt
def paypal_ipn_listener(request):
print request.POST
print request.body
The data in request.POST is in QueryDict which is unordered, thus doesn't suit my needs.
Trying to access request.body throws an exception:
RawPostDataException: You cannot access body after reading from request's data stream
I think this exception happens because of my #require_POST or #csrf_exempt decorators which perhaps call some middleware which reads POST data stream.
Anyway my question is how do I get HTTP request POST data in exact order?
I need to keep the order to satisfy PayPal IPN implementation requirements.
** UPDATE **
I ended up manually parsing request.body since there is no better solution.
What if you delete #require_POST and do something like this?:
from django.http import Http404
#csrf_exempt
def paypal_ipn_listener(request):
if request.method != 'POST':
raise Http404('some error')
print request.body
Related
I would like to set up my URLs/endpoints according to REST as closely as possible, while still utilising Flask-WTForms.
I would like my form to render at GET /posts/new, and submit to POST /post.
With Flask-WTForms I can only work out how to get it to GET/POST to the same URL.
My current code looks like this:
#post_bp.route('/posts/new', methods=['GET', 'POST'])
def show_post_form():
create_post_form = CreatePostForm()
if create_post_form.validate_on_submit():
return 'success'
return render_template('create_post_form.html', form=create_post_form)
However I would like to be able to make it look something more like this, but I just can't seem to work it out:
#post_bp.route('/posts/new', methods=['GET'])
def show_post_form():
create_post_form = CreatePostForm()
return render_template('create_post_form.html', form=create_post_form)
this route only shows the form
the form submits a POST request to /post
<form action="{{url_for('shipment.C_shipment')}}" method="POST" novalidate>
the POST /post route handles the submitted form and if there are errors for example, then it redirects back to GET /posts/new:
#post_bp.route('/post', methods=['POST'])
def create_post():
create_post_form = CreatePostForm()
if create_post_form.validate_on_submit():
return "success!"
if len(create_post_form.errors) != 0:
for error in create_shipment_form.errors:
for msg in create_shipment_form.errors[error]:
flash(msg)
return redirect(url_for('shipment.show_create_shipment_form'))
i guess creating a new CreatePostForm() object here doesn't really work..
Any suggestions?
Creating a new CreatePostForm is correct as it parses the submitted form data for you. This allows you to call validate_on_submit() on the form object.
I don't think you're generating the correct URL for the form action in your HTML snippet. The argument to url_for() should be the desired endpoint (see docs) which should be <post_bp>.create_post. This would be similar to your call
return redirect(url_for('shipment.show_create_shipment_form'))
If this does not fix the issue, please provide both frontend and backend error messages you receive when trying to send the data to /post.
In the twilio example made in flask, I can send an SMS and receive an answer using text and the SMS as the search parameter in the database. I need make this but in a django project, my first option that I thought make a django view with a parameter using a url with for send the parameter, but I see that is bad idea because not is possible can use the text of SMS as parameter
This is a part of flask example
#app.route('/directory/search', methods=['POST'])
def search():
query = request.form['Body']
I need make some similar to that view in django using django restframework but how I can get the Body (I think that the body is the text send in the SMS)
for use this as parameter
Use request.POST to access the form data:
from django.shortcuts import render
def my_view(request):
if request.method == "POST":
data = request.POST
# all posted data
data['body']
# the rest of your view logic
return render(request, 'template.html', context)
I'm using Django and have a view to get/insert some records in database. Here's my code:
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
#api_view(('GET','POST'))
#renderer_classes((TemplateHTMLRenderer,))
#csrf_exempt
def cours_list(request):
if request.method == 'GET':
data = JSONParser().parse(request)
results = Lesson.objects.get(discipline=data.discipline)
return Response({'cours': results}, template_name='search_results.html')
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = LessonSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data, status=201)
return JSONResponse(serializer.errors, status=400)
So to get data I use GET and to insert a new record I use POST. First, is this the right way to do ? I read once that it't a bad idea to use GET whatever the situation.
Also, the GET code is not actually working (I'm getting a bad request error) and it seems that this is comming from JSONParser that is not able to parse the request.
Edit1
Here is the request that is sent:
GET http://127.0.0.1:8000/cours/?{%22discipline%22:%22Mathematiques%22,%22localisation%22:%22%22}
Edit2
I tried to print requet.GET, and this what it gives:
<QueryDict: {'{"discipline":"Mathematiques","localisation":""}': ['']}>
When trying to access request.data['discipline'], it says:
django.utils.datastructures.MultiValueDictKeyError: "'discipline'"
Should I use GET or POST to retrieve results Django
To retrieve use a GET
I read once that it't a bad idea to use GET whatever the situation
Not at all, as long as your GET operation contains no side effects (e.g. in your GET method you are only reading from the database.
The GET code is not actually working (I'm getting a bad request error)
data2 = JSONParser().parse(request) # you used data2
results = Lesson.objects.get(discipline=data.discipline) # and you used data
^
|____ data? data2?
You're not passing the GET parameters correctly
You need to pass GET params like this url/?param1=value1
To read that value you use param1 = request.GET['param1'] and param1 will be the string value1
What you are doing isn't passing a value:
GET http://127.0.0.1:8000/cours/?{%22discipline%22:%22Mathematiques%22,%22localisation%22:%22%22}
That's why you get an empty value ['']
<QueryDict: {'{"discipline":"Mathematiques","localisation":""}': ['']}>
You can pass the entire data as a JSON string if you want, but I prefer to break it down like this:
url/?discipline=Mathematiques&localisation=Quelquechose
with
discipline = request.GET['discipline']
localisation = request.GET['localisation']
That's absolutely normally to use GET method for information retrieving, see HTTP/1.1: Method Dediniton, 9.3:
The GET method means retrieve whatever information (in the form of an
entity) is identified by the Request-URI. If the Request-URI refers to
a data-producing process, it is the produced data which shall be
returned as the entity in the response and not the source text of the
process, unless that text happens to be the output of the process.
For POST method, it's a good practice to submit new data with POST request, see HTTP/1.1: Method Dediniton, 9.5:
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. POST is designed to
allow a uniform method to cover the following functions:
................................................................
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation.
Also, take a look at Which HTTP methods match up to which CRUD methods? it will give you more clear idea of how and when particular HTTP methods shall be used and help you in next further development.
For both GET and POST requests I simply want to print the associated QueryDict in my test view:
if request.method == 'GET':
print request.GET
if request.method == 'POST':
print request.POST
When I make requests using both methods I get different response codes. I could use some help.
The post request has triggered Django's CSRF protection so you are getting a 403 Forbidden response.
Usually, it means that you need to include the CSRF template in your template.
In this case, because you are making requests from the shell, it might be appropriate to use the csrf_exempt decorator on this view to disable the CSRF protection.
Hi so I have this method in django views to post the file to a different server. I get an HTTP 415 error complaining about the media type of the request. I have debugged the request and copied and pasted its contents in fiddler. When I posted the same from fiddler it worked. So I don't understand why it does not work using python requests package.
Can anyone help me with this?
Thanks.
def upload(request):
if request.method == 'POST':
url=settings.WEBSERVICES_URL+'validate'
r = requests.post('http://localhost:9090/validate',data=request)
r2 = requests.get('http://localhost:9090/test')
return render_to_response("upload.html", context_instance=RequestContext(request))
else:
return render_to_response("upload.html", context_instance=RequestContext(request))
Do this:
r = requests.post('http://localhost:9090/validate', data=request.POST)
You are passing a full django.http.HttpRequest object to requests.post, when you only need its post data.
If you look at the documentation of requests it says about the data keyword:
data – (optional) Dictionary, bytes, or file-like object to send in the body of the Request.
Django's request object is an instance of HttpRequest.You should try to put the necessary data in a dictionary and pass it to post().