how to update request.user in django? - django

I have an ajax call which sets
request.user.my_field = value
When the ajax succeeds, I reload the page with location.reload(True)
I expect the request.user.my_field in the view function is updated now but it has the old value.
How can I fix this?
EDIT
The ajax call:
$.ajax({
type: 'POST',
url: '{% url editor_select %}',
data: {'editor_type':$(this).val(),
success: function(response_data) {
location.reload(true);
}
}
});
The first view:
def editor_select(request):
"""
called when user changes editor type to post question/answer
"""
editor_type = CharField().clean(request.POST['editor_type'])
request.user.editor_type = editor_type
request.user.save()
The second view:
def second_view(request):
print 'ask, editor_type:', request.user.editor_type
I find AuthenticationMiddleware (which sets request.user to request), doesn't get called in between the ajax call and the location.reload()
so umm???

Save the model before exiting the view.
request.user.save()

Wow shoot me..
success: was inside data and it requested two pages in succession.

Related

Django REST giving a 403 forbidden on DELETE methods, but not POST

I am trying to delete an entry using an ajax call.
when I am using the default 'delete' method from generics.DestroyAPIView, I am getting a 403 Forbidden, but if I add a post method, call the delete method immediately and change the ajax type to 'post' it works fine. Would anyone have an idea what causes this?
Note that I overwrite the get_object function to get the object based on posted data. (could it be due to delete methods not allowing to post data? If so, why? And how would you pass the CSRF token??)
ajax:
$.ajax({
url: '{% url "account:api:post_details_delete" %}',
type: 'delete',
data: { csrfmiddlewaretoken: "{{ csrf_token }}", name: json.name, value: json.value }
});
url:
path('post_details/delete/', PostDetailDeleteApiView.as_view(), name='post_details_delete'),
view:
class PostDetailDeleteApiView(generics.DestroyAPIView):
serializer_class = PostDetailSerializer
# the code below allows it to work if uncommented and type in ajax changed to 'post'
# def post(self, request, *args, **kwargs):
# return self.delete(request, *args, **kwargs)
def get_object(self):
"""
Returns the post detail object to be deleted based on the name:value pair
provided by the ajax call.
"""
data = self.request.data
obj = Post_Detail.objects.filter(
name=data.get('name', ''), value=data.get('value', '')
).filter(
post__account__user=self.request.user
)
if obj.exists():
return obj.get()
else:
raise Http404
serializer:
class PostDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Post_Detail
fields = ['name', 'value']
A 403 Forbidden error code would suggest that in some way or another that either permission is denied or that you're not authenticated.
The 'DestroyAPIView' is used for delete-only API endpoints for a single model instance.
Do you have the full traceback that you can append to your question?
Docs References
Django REST Framework's Destroy API View
Django REST Framework's Guide to Permissions
According to Django documentation you must pass the csrftoken to headers of ajax request
While the above method can be used for AJAX POST requests, it has some inconveniences: you have to remember to pass the CSRF token in as POST data with every POST request. For this reason, there is an alternative method: on each XMLHttpRequest, set a custom X-CSRFToken header (as specified by the CSRF_HEADER_NAME setting) to the value of the CSRF token. This is often easier because many JavaScript frameworks provide hooks that allow headers to be set on every request.

Django redirect is not working with dropzone.js

Redirect in Django is not working when files are uploaded using Dropzone.js, so I used windows.href in the Dropzone success event but I have to pass a parameter.
views.py:
if request.method == 'POST' and request.FILES['files']:
...
if form.is_valid():
....
user = User.objects.get(email=email)
id = user.id
return redirect(reverse('success', kwargs={'id': id})) <<-- not working
JQuery - Dropzone:
this.on('success', function() {
window.location.href = '/success/';
})
I don't reckon there is a way to pass the id to JQuery in this case, so I have to use redirect in Django. How can it get done?
The reason why django redirect is not working is because dropzone.js uses AJAX for its post requests which doesn't redirect pages.
To get the redirect to work you need to get the dropzone to redirect with javascript to the correct url given as a response from the POST request. The view returns a JSON response that then can be parsed from the js. This is done as follows:
from django.http import JsonResponse
def index(request):
if request.method == 'POST':
form = BenchmarkForm(request.POST, request.FILES)
if form.is_valid():
model_id = YourModel.objects.create(file=request.FILES['file']).id
link = reverse('energy:benchmark',kwargs={'id':model_id})
response = {'url':link}
return JsonResponse(response)
Then in the dropzone init function you need to parse the response in the success callback.
Dropzone.options.myDropzone = {
// Prevents Dropzone from uploading dropped files immediately
autoProcessQueue : false,
url: "{% url 'energy:index' %}",
headers: {
"X-CSRFToken": "{{ csrf_token }}"
},
init : function() {
mydropzone = this;
this.on("success", function(file, response) {
window.location.href=JSON.parse(file.xhr.response).url
});

Django turn off redirect after login

Is there a way to completely turn off redirection after user login? I just can't find out how to do this... I just don't need any additional queries after login, because it's happening in modal window. I tried to set LOGIN_REDIRECT_URL = None or LOGIN_REDIRECT_URL = '' in settings, none of this works. Am I missed something?
So from what i understood you want the login required page to be a modal.
You can't accomplish that using django's login_required, instead you can use ajax.
This must be in your views:
def login_required_ajax_view(request):
if request.is_ajax():
if request.user.is_authenticated():
return JsonResponse(data={'logged_in', True})
return JsonResponse(data={'logged_in', False})
return HttpResponse("not ajax") # Add something if the call isn't ajax
And this is going to be your javascript in the page:
function login_required() {
$.ajax({
url: 'url goes here',
data: data
success: success //on success call a function checking logged_in is
//true or false then open modal to log in.
})}
If it returns true allow them to click the button and move on to the next page.

Django CSRF on 500 error page with a form

I got a 500 error page which has a form, however the CSRF token is not generated when 500 error page is thrown. What's the best way to generate the CSRF token on a 500 error page to make the form post work? Should I just define my own custom 500 error view?
OK, I tried defining the custom 500 view and worked, for anyone who has the same issue, here it's how:
define a custom 500 error view
from django.shortcuts import render
def server_error(request):
vars = {}
return render(request, '500.html', vars, status=500)
then in the main urls.py add:
handler500 = 'your_app.views.errors.server_error'
You have to pass the token on the ajax request
var data = {
errorresponse: errorresponse,
'csrfmiddlewaretoken': '{{ csrf_token }}',
}
$.ajax({
type: "POST",
url: "/your-target-url/",
data: data, // this passes data context into view
success: function(data) {

Post data isn't be sent with jquery / django

I'm trying to perform a simple post to django that will take in a variable and then redirect the user to another page. Right now, my javascript looks like this:
$.ajax({
type: "POST",
url: "{% url unity.survey.views.post %}",
data: { // <-- error here?
'order' : '1',
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(datas) {
if (datas.redirect) {
window.location.href = data.redirect;
}
}
});
};
My corresponding view in django looks like so:
def post(request, *args, **kwargs):
if 'order' in request.POST:
order = request.POST['order']
else:
return redirect('unity.survey.views.login')
.... some calculations with order ....
return render_to_response(
'template.html',
some_dictionary,
context_instance=RequestContext(request)
)
For some reason, it appears that nothing is sent to the view. Looking at Firefox's web console, I see:
[07:31:12.414] POST http://127.0.0.1/unity/ survey/ [undefined 17ms]
[07:31:12.422] GET http://127.0.0.1/unity/survey/ [HTTP/1.1 302 FOUND 73ms]
[07:31:12.497] GET http://127.0.0.1/unity/survey/login [HTTP/1.1 200 OK 177ms]
It just redirects me to the login page regardless of what I do. I've tried using .post instead of .ajax, but it results in the same thing. Any idea why this might be the case? I have a similar function and it works great but for some reason I can't get this to work. It just appears as if no POST data is being sent.