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)
Related
I have the following python code in my Django views.py, the code takes in a JSON body and send the extracted DATA to another API endpoint, I have simplified the code here.
How do I enable csrf such that it will send the token back to the caller for this method? I am calling this from postman.
#csrf_protect
def validate_booking(request):
if request.method != "POST":
return HttpResponseServerError("Invalid HTTP method")
body = json.loads(request.body)
booking_details = body["booking_details"]
DATA = {
"name": booking_details["name"],
"nric": booking_details["nric"],
"booking_id": booking_details["booking_id"]
}
return HttpResponse(status="200")
This site directs to put this piece of code in my method. But what is "a_template.html"?
https://docs.djangoproject.com/en/4.1/ref/csrf/
#csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
This isn't an easy thing to do as CSRF is 2 steps thing
There is a value that is passed to the client and it is saved to the session on the server.
When a POST request is received, the client shall send this as csrfmiddlewaretoken in the body and the server will check the value against the stored one in the server's session.
So this isn't feasible to be done in APIs as you require session Management which is not of REST API implementations.
Thanks for your reply. I managed to find a solution by doing the following:
Create a new GET method that will generate the session CSRF token using python
Instead of using render which expects a HTML template file, I used JsonResponse(data) to return in JSON format directly
In my postman app which I am making the POST request with the X-CSRFToken in the header, I will first make a GET request to the new method I created in step 1 to retrieve the token and store it as an environment variable
The following is the GET method sample:
from django.http import JsonResponse
def get_csrf_token(request):
csrf_token = csrf(request)['csrf_token']
data = {'csrf_token': csrf_token}
return JsonResponse(data)
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.
I just started to learn Django by following a sentdex tutorial. During the course, we added a User model into our database and we created a function in our views.py file:
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():#si les champs sont OK :
user = form.save()
login(request, user)
return redirect("main:homepage")
else:
for msg in form.error_messages:
print(form.error_messages[msg])
But in this piece of code, I don't understand how Django knows if the request.method is True or False. Is it because I created a form with a Submit button in my template ?
Its impossible to say exactly what happens in your case since we don't have your HTML but in general:
When you create an HTML form, you can specify a method as follows <form method="POST"></form> or <form method="GET"></form>. If you don't specify the default is GET.
When you submit your form, it sends the data using an http request of the specified type. This is what Django is reading.
In this case, request.method simply represents the HTTP method that was used to access your view. For example, your register function might be assigned a url configuration such as: url(r'^register/', views.register), which maps an incoming HTTP request to your view. If you have a web form with a 'Submit' button, it's likely the web application code is submitting an HTTP POST request to your web server.
Django automatically constructs the request object for you, so you can check in your view how the request was made against the web server. For more info about what other things are included in the request, check the Django docs.
I'm new in web dev and I'm trying for a project to develop a Restful web api and a website. I'm using Django framework and following tutos, I always see html files as static and the different views rendering an html template. This way of doing seems to me as backend and frontend are not much separated. Is it possible to have backend only developed in Django ?
edit:
I have actually a problem more specific. I having this app (records) with a view having "patient_list" using Response class from REST framework that renders some data and an html template like this:
def patient_list(request):
"""
List all records, or create a new .
"""
if request.method == 'GET':
#data = Patient.objects.all()
data= Patient.objects.all()
#serializer = PatientSerializer(data, many=True)
#return JSONResponse(serializer.data)
return Response({'patients': data}, template_name='records.html')
in my urls.py I have:
url(r'^records/$', views.patient_list),
and here I'm a little confused. Suppose one called this /records, so patient_list is called and will response with an html page. From what I understood (maybe wrong), a restful API should renders data in a standard view so that it can be used from any "frontend" (html pages or mobile app). Is this statement correct ? am I doing it wrong using Response with an html template ?
With Vanilla Django
Of course it's possible, and without any additional libraries to Django.
E.g. You can define a Django view that returns JSON data instead of rendering it into a HTML template server-side. Effectively making an API instead of a "website".
Here's an example with a class-based view that accepts GET requests and returns some JSON data with JsonResponse
from django.views.generic import View
from django.http import JsonResponse
class MyView(View):
def get(self, request):
my_data = {'something': 'some value'}
return JsonResponse(my_data, mimetype='application/json')
As you can see, you don't have to use the HTML rendering facilities in Django, they're there only if you want to use them.
With REST libraries
And of course there is a host of libraries to build RESTful APIs with Django, like Django REST Framework and Tastypie
Multiple representations and content negotiation
Content negotiation is the process of selecting one of multiple possible representations to return to a client, based on client or server preferences.
You can support more than one format in your REST API. E.g. you can support both HTML and JSON formats. There are various ways to do this:
You may use a GET param ?format=JSON (and have it default to HTML e.g.)
You may use Accept headers
You may have two URLs /records.html and /records.json (the format suffix method)
More on this topic in DRF's documentation
E.g. if you were to implement the first method with the GET params you could modify your code this way:
if request.method == 'GET':
data = Patient.objects.all()
format = request.GET.get('format', None)
if format == 'JSON':
serializer = PatientSerializer(data, many=True)
return JSONResponse(serializer.data)
else:
# Return HTML format by default
return Response({'patients': data}, template_name='records.html')
I have a translation engine api made using Django Python and it has a function that I want to be made into a class based view:
def i18n_newkey(rin):
request = Request(rin, JSONParser())
if request.method == 'POST':
data = json.loads(rin.body)
.... # Parsing and other code here and finally,
return JSONResponse(kdata)
Where the JSONResponse is an HttpResponse that renders it's content into JSON.
My url: url(r'^savekey', 'i18n_newkey'),
I'm new to django and I wanted to convert my function based view to class view, I've read the Django Documentation but I cannot seemed to dig it in this particular code.
Thanks!
Seems like JsonRequestResponseMixin will do exactly what you want.