Django session and Dojo dnd.

144 views
Skip to first unread message

voss

unread,
Jun 1, 2012, 9:31:24 PM6/1/12
to django...@googlegroups.com
I have a Dojo drag-and-drop and hope to store the dropped items and their information in a Django session. Using the example below, how do I pass "detail" in this code to a view so that the dropped info can be stored in a session?

Thank you!


        var source1 = new dojo.dnd.Source("itemListNode");
        var source2 = new dojo.dnd.Target("selectedListNode");

        dojo.connect( source1, "onDndDrop",
                              function(source, nodes, copy, target){
                                            for( i=0; i < nodes.length; i++){
                                                          item = this.getItem(nodes[i].id);
                                                          detail = item.data;
                                                          .....................................
                                                          .....................................
                                            }
                               }
        )

henzk

unread,
Jun 2, 2012, 1:46:38 PM6/2/12
to Django users
Hi,

i haven't tested the code and never used dojo before, but sth. like
this should work:

var source1 = new dojo.dnd.Source("itemListNode");
var source2 = new dojo.dnd.Target("selectedListNode");
dojo.connect( source1, "onDndDrop",
function(source, nodes, copy, target){
//gather items and details
var details = [];
for( i=0; i < nodes.length; i++){
var item = this.getItem(nodes[i].id);
details.push(item.data);
}
//send details to server via AJAX POST request
dojo.xhrPost({
url: "/save_details/",
content: {details: JSON.stringify(details)},
// The success handler
load: function(response) {
alert('ok');
},
// The error handler
error: function() {
alert("error");
}
});
});

Explanation:

- changed 'item' to 'var item' ... without the 'var' item will be
global, which is probably not what you want.
- to get around making multiple requests to the server(one for each
dropped node), put the detail of each node in the details array.
- then json-encode and send this array to your django view (assumed to
be at '/save_details/')
- in the view, access the list as
json.loads(request.POST.get('details', '[]')) and place it into
request.session

As mentioned, the code is completely untested.

Good luck!

Yours,

Hendrik Speidel

voss

unread,
Jun 4, 2012, 4:23:54 PM6/4/12
to django...@googlegroups.com
Hello Hendrik,

Thank you for your help! I can get the 'ok' in the alert with your code. However, how do I show the response in the alert? For some reason I am unable to pass the message back from the view; I keep getting an empty alert(response).

My view looks like:
 
   def new_session(request):
      if not request.is_ajax() or not request.method=='POST':
          return HttpResponseNotAllowed(['POST'])
   
      else:
          request.session['key'] = json.loads(request.POST.get('details', '[]'))
          return HttpResponse(request.session['key'])

I've also tried "return HttpResponse('ok')", but the 'ok' still didn't get passed to the load function. What do I do wrong? Any hints would be much appreciated!

    voss

voss

unread,
Jun 4, 2012, 4:33:21 PM6/4/12
to django...@googlegroups.com
Hi Hendrik,

I forgot to mention in my previous message that the debug shows the following:

code 400, message Bad request syntax ("\x16\x03\x01\x00\x8b\x01\x00\x00\x87\x03\x01O\xcc\xd8\xc0\x18hZ\x7f\xa3h\xb9l\xaf\xdb\xfbp}(\xc1\xc6\xa5g\x18\xe5!\x87\xd4\xe2`_'\x90\x00\x00H\x00\xff\xc0")

Thank you!


    voss



On Saturday, June 2, 2012 8:46:38 AM UTC-5, henzk wrote:

henzk

unread,
Jun 5, 2012, 1:21:15 AM6/5/12
to django...@googlegroups.com
Hi Voss,

i forgot about django's CSRF protection.
You can use the csrf_exempt decorator on the view function to disable django's CSRF protection - however, i wouldn't recommend that.

To use the script with dojo instead of jquery, you will need to adapt it a little:

-copy the getCookie function to your code

then, every time you make a POST request to your application using dojo.xhrPost, add this to the arguments object:

headers: {'X-CSRFToken': getCookie('csrftoken')}

If you are still getting HTTP 400 errors, verify that the request looks sane in firebug and check that it contains a X_HTTP_REQUESTED_WITH header set to XMLHttpRequest (but i am pretty sure dojo adds this one automatically).

hendrik

voss

unread,
Jun 5, 2012, 1:34:35 PM6/5/12
to django...@googlegroups.com
Hello Hendrik,

Thank you for the explanation. It is *very* helpful!

   voss

voss

unread,
Jun 7, 2012, 4:17:11 PM6/7/12
to django...@googlegroups.com
Hello Hendrik,

To simplify things and to do some tests, I started with disabling the csrf protection. Here is my JS:

                    dojo.xhrPost( {
                        url: "/test/",
                        content: {details: JSON.stringify(details)},
                        load: function(response){
                            alert(response);
                            },

                        error: function(){
                            alert("error");
                            }
                    });


In views.py, I have:

                    @csrf_exempt
                    def new_session(request):
                        if request.is_ajax():
                            return HttpResponse('ok')


In theory, I should see the 'ok' alert, but, instead, I got "null". The debug message shows:

[07/Jun/2012 10:31:06] code 400, message Bad request syntax ('\x16\x03\x01\x00\x8f\x01\x00\x00\x8b\x03\x01O\xd0\xc9:}m\x9e\x04\xbf_:$`\x96v\xca\x1b\x92\xb8\xc7?M\x0f\xbdc\x8e\xfb+\x84E\x8c?\x00\x00H\x00\xff\xc0')
[07/Jun/2012 10:31:06] "??O??:}m??_:$`?v????M?c??+?E??H??" 400 -

This error message looks similar to that before the csrf_exempt decorator was added, which suggests to me that the problem may not be in the csrf protection. Am I right? Any thoughts would be greatly appreciated!


    voss


On Monday, June 4, 2012 8:21:15 PM UTC-5, henzk wrote:

Hendrik Speidel

unread,
Jun 7, 2012, 4:32:14 PM6/7/12
to django...@googlegroups.com
Hi Voss,

i guess you are right ... it may not be related to CSRF-Protection at all.
Are you using the django development server? I have found some references for '\x16\x03\x01' using google, e.g.
http://wishmesh.com/2010/05/apache-logs-contains-x16x03x01-when-accessing-site-via-https/

It seems that this is related to browsers that speak HTTPS to a (misconfigured) HTTP server.

Can you verify that this happens also when using the django devserver on port 8000?
Another thing you could try is to get rid of the is_ajax check.
In either case you should return a response for non-ajax requests also ... otherwise you will provoke a HTTP500 in these cases.

hendrik
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/CWKY_xRFelAJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

voss

unread,
Jun 7, 2012, 4:58:59 PM6/7/12
to django...@googlegroups.com
Hi Hendrik,

Thank you for your prompt reply. I really appreciate it!

Yes, I am using the django development server, and it is on port 8000.  I, too, read that the https can cause the '\x16\x03\x01' problem, but I don't see how this can happen in my case because I did not create any https'.

Although it may not be csrf, do you think csrfmiddlewaretoken: '{{ csrf_token }}' could be the missing piece (see http://stackoverflow.com/questions/9085068/django-jquery-get-to-post)? It seems to make sense to me because {% csrf_token %} is required for a normal post request. If so, how do I use it in dojo.xhrPost? I tried 


                    dojo.xhrPost( {
                        url: "/test/",
                        content: {
                            details: JSON.stringify(details)
                            csrfmiddlewaretoken: '{{ csrf_token }}'

                        },
                        load: function(response){
                            alert(response);
                            },
                        error: function(){
                            alert("error");
                            }
                    });


, but it did not change anything. I also commented out the is_ajax line, but I got the same debug message.


    voss
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.

Hendrik Speidel

unread,
Jun 7, 2012, 6:04:27 PM6/7/12
to django...@googlegroups.com
Hi Voss,

you were missing a comma after "details: JSON.stringify(details)"
However, i don't think that was the cause of the problem. When using csrf_exempt you do not need to include the csrf token.

I have now created a test project and it's working here. The project is called 'testp' and the app is called 'testa'

#testp.urls
from django.conf.urls import patterns, include, url

urlpatterns = patterns('',
    url(r'^dojo/$', 'testa.views.dojo'),
    url(r'^test/$', 'testa.views.new_session'),
)

#testa.views
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render
from django.http import HttpResponse

def dojo(request):
    return render(request, 'dojo.html')


@csrf_exempt
def new_session(request):
    if request.is_ajax():
        return HttpResponse('ok')
    else:
        return HttpResponse('only AJAX requests are allowed!')

#dojo.html
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js"></script>
<script>
    var details = [1,2,3,4,5]

    dojo.xhrPost( {
        url: "/test/",
        content: {details: JSON.stringify(details)},
        load: function(response){
            alert(response);
            },
        error: function(){
            alert("error");
            }
    });
</script>
</head>
<body>

If i visit localhost:8000/dojo/ it alerts 'ok'

Maybe you can deduce your error by comparing this to your setup.
Also, do you have a debugging tool like firebug? It really helps me out quite often.

Good luck!

hendrik
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/zX59VNkLB-gJ.

To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.

voss

unread,
Jun 7, 2012, 6:30:39 PM6/7/12
to django...@googlegroups.com
Hello Hendrik,

Your code works on my machine, too!! I don't know what is wrong with my code. I will definitely compare it carefully to yours. Hopefully, I will find the cause soon.

By the way, I do have firebug running all the time, but it does not show any errors.

Once again, thank you so much for all your help! Your help is very much appreciated.
   voss

voss

unread,
Jun 7, 2012, 6:48:07 PM6/7/12
to django...@googlegroups.com
Hi Hendrik,

THANK YOU, THANK YOU, and THANK YOU!! I found it!! I made a mistake when defining the url, and that's why I kept getting the "code 400" error.

Your test code is extremely beneficial! I can't thank you enough for all your help!

   voss

Hendrik Speidel

unread,
Jun 7, 2012, 7:34:23 PM6/7/12
to django...@googlegroups.com
Hi Voss,

you're welcome. Great that you got it working.

hendrik
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/8GbAcKPsrUwJ.

To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages