Django HttpResponseRedirect wont redirect when message sent - python

I want my page to reload and show the django messages sent to the page when a POST call is made (by another user).
From api I am calling the method like that:
def create(self, request, pk=None):
json_data = json.loads(request.body)
sample_path = json_data['sample_path']
try:
sample = BloodSample.objects.get(sample_path = sample_path)
if json_data['status'] == 201:
BloodSampleAdmin(sample, BloodSample).display_messages(request, sample)
return Response(json_data['body'], status = status.HTTP_201_CREATED)
and the method in BloodSampleAdmin is:
def display_messages(self, request, sample):
messages.success(request, ("hurray"))
return HttpResponseRedirect(reverse(
"admin:backend_bloodsample_change",
args=[sample.id]
))
I am 100% sure that the method is called (debug). But message wont pop anyway.
I am using Postman to send the POST request.
Any ideas on what is going wrong?

Related

How to redirect to page where request came from in Django

I currently work on a project an i want to redirect to page where request is came form, when request method is GET.
this is my views.py file
Views.py
def delete_patient(request):
if request.method == 'POST':
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
else:
// //
so please tell me what I want to write in else part of view.
Typically for that, the server responds with a 405 method not allowed. Especially since it is not even said that the request "comes from somewhere". For example one can make such request with curl, wget, etc. You can work with a #require_POST decorator [Django-doc] for example to return a 405 in case the method is something else than a POST (GET, PUT, PATCH, etc.):
from django.views.decorators.http import require_POST
#require_POST
def delete_patient(request):
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
If you really want to redirect to the referring page, you can try to access the HTTP_REFERER key from the request.META dictionary. But not all browsers per se send the referring page, and it is not even said that the request comes from a web client in the first place.
You thus can work with:
from django.http import HttpResponseNotAllowed, HttpResponseRedirect
def delete_patient(request):
if request.method == 'POST':
patient_id = request.POST['patient_id']
rem = Patient.objects.get(pk=patient_id)
rem2 = CustomUser.objects.get(aid=patient_id, role=4)
rem.delete()
rem2.delete()
return JsonResponse({'delete': 1})
elif 'HTTP_REFERER' in request.META:
return HttpResponseRedirect(request.META['HTTP_REFERER'])
else:
return HttpResponseNotAllowed(['POST'])

Django: Forbidden (CSRF cookie not set.), Why this is happening , and How to fix it [duplicate]

This question already has answers here:
#csrf_exempt does not work on generic view based class
(4 answers)
Closed 3 years ago.
I wrote a test file to check if the URL works or not and it keeps printing Forbidden (CSRF cookie not set.) could please check what's the problem
#post handler
#csrf_exempt
def post(self, request, *args, **kwargs):
valid_json = is_json(request.body)
if not valid_json:
error_data = json.dumps({'message': 'Invalid data sent, please send using JSON format'})
return self.render_to_response(error_data, status=400)
data = json.loads(request.body)
form = SupervisorForm(data)
if form.is_valid():
obj = form.save(commit=True)
obj_data = obj.serialize()
return self.render_to_response(obj_data, status=201)
if form.errors:
data_error = json.dumps(form.errors)
return self.render_to_response(data_error, status=400)
json_data = json.dumps({'message': 'Not Allowed'})
status_code = HTTP_400_BAD_REQUEST
return self.render_to_response(json_data, status_code)
def post():
data = {
'supervisor_name':'name',
'supervisor_phone': '76786875',
'supervisor_email': 'sdsds#sdsd.com',
'supervisor_image': 'path to local image',
}
json_data = json.dumps(data)
json_loads = json.loads(json_data)
print(type(json_data))
print(type(json_loads))
print(help(requests.put))
r = requests.put('http://127.0.0.1:8000/api', json = json.dumps(data))
return r.json()
You have probably configured your Django to use a CSRF token but have not set it up for your API. Are you able to disable CSRF in your configuration? Otherwise, you'd have to set it up in accordance with the documentation
CSRF is important for websites that are at a high risk of getting hacked through scripts/iframes. CSRF is what prevents your bank account from sending money to a hacker via email/popup scripts. Unless you're building a website that has confidential data scoped to the user (e.g. Facebook, Venmo, PayPal) CSRF is not necessary.

implementing flask_jwt_extended with templates rendering

Again fighting trying to make my first flask application, this time, (after I created every I need and all works smoothly) I'm trying to protect some endpoints with flask_jwt_extended, but I can't find how to work with them in my pages, the documentation is mostly about displaying JSON messages and some tutorials use postman while in my case I'm using HTML templates.
For example, a user sends his credentials from the login page to this endpoint :
#app.route('/login', methods=['POST'])
def UserLogin():
data = parser.parse_args()
current_user = UserModel.find_by_username(data['username'])
if not current_user:
return {'message': 'User {} doesn\'t exist'.format(data['username'])}
if UserModel.verify_hash(data['password'], current_user.password):
access_token = create_access_token(identity = data['username'])
refresh_token = create_refresh_token(identity = data['username'])
resp = jsonify({'login': True}) #I just added this line from the documentation
set_access_cookies(resp, access_token) # and this one
set_refresh_cookies(resp, refresh_token) # and this one
return redirect(url_for('results'))
else:
return {'message': 'Wrong credentials'}
and of course, I added the #jwt_required decorator the results endpoint:
#app.route('/result',methods = ['POST','GET'])
#jwt_required
def results():
temp={}
if request.method == 'POST':
# some code to fill temp with values
return render_template('result.html',data=temp)
So I'm getting a {
"msg": "Missing cookie \"access_token_cookie\""
}Obviously because I'm not sending the jwt back but if send it in the return statement how can I redirect the user the page I want ?? And indeed I used app.config['JWT_TOKEN_LOCATION'] = ['cookies']
You may want to:
resp = make_response(redirect(url_for('results')))
set_access_cookies(resp, access_token)
set_refresh_cookies(resp, refresh_token)
return resp
I don't think you need this line! --> resp = jsonify({'login': True})
Took me a while to figure it out, not sure why this part is not clear in the docs, most of the examples there just returns JSON directly
Also, you get same error if JWT_ACCESS_COOKIE_PATH is routed wrongly.

get user with token django rest framework

sorry for my english. It is not good.
I work with rest framework django. I want to recover a user with his token. This Token must be sent via a post request
class GetUser(generics.ListCreateAPIView):
serializer_class = serializers.UserBasicSerializer
def get_queryset(self):
return models.Member.objects.filter()
def post(self, request, *args, **kwargs):
user = Token.objects.get(*args, **kwargs).user
i receive this error message
rest_framework.authtoken.models.MultipleObjectsReturned: get() returned more than one Token -- it returned 2!
thanks
Use:
user = Token.objects.filter(*args, **kwargs)
if user.exists():
user = user.last().user
The answer to your question is in the docs. Take a look here: http://www.django-rest-framework.org/api-guide/requests/#user
Basically, you just need to get from request the method user. For example:
def api_name_of_api(request):
user_data = request.user # Get username
user_data = request.user.id # Get user id
...

Flask login_required + next url params

I have a protected view in my app which just accepts POST requests.
#app.route("/booking", methods=("POST", ))
#login_required
def booking():
arg1 = request.form.get("arg1")
arg2 = request.form.get("arg2")
When an unauthorized user tries to access this view, I want them to
login and then be redirected here.
Right now, my login view looks like this:
#app.route("/login", methods=("GET", "POST"))
#login_required
def login():
do_login()
return redirect(request.args.get('next') or url_for('home'))
So what ends up happening is a POST request to /booking (which is the
"next" parameter) and I get a NOT ALLOWED error.
The problem is that login() makes a GET request to booking(). I can
get around that, but I am not sure how to retrieve the original POST
form arguments from /booking? Any ideas to get round that?
I would solve this by pulling the data and putting it in the session. You can remove the #login_required decorator and check this in the function using current_user.is_authorized. See Flask Sessions and Flask Login.
Something like this might work for you, I didn't test it:
from flask import session
from flask_login import current_user
#app.route("/booking", methods=("POST", ))
def booking():
if not 'arg1' in session.keys() and not 'arg2' in session.keys():
session['arg1'] = request.form.get("arg1")
session['arg2'] = request.form.get("arg2")
# Now the data will persist in the session
if current_user.is_authorized:
# Do what you need...
else:
# Redirect to login, session will persist
Why would you only use POST in the booking view ? You are probably rendering a form which should also allow GET.
#app.route("/booking", methods=['GET','POST'])
#login_required
def booking():
# render the form. something like
form = BookingForm()
# Check if POST
if request.method == 'POST':
# process the form now and do whatever you need.
return redirect(url_for('index'))
# code below will run if not POST. You should render the template here
return render_templte('booking.html')

Categories

Resources