0

There are a lot of gaps in my knowledge, so I may be trying to solve this the wrong way. The goal is to use this Google Maps JavaScript API to autocomplete and parse address input, and save the results in a model.

I couldn't find a way to pass variables from JS directly to view.py, so now the plan is to have the JS fill a hidden field as suggested by a previous unsolved question.

Could the fields generated by a ModelForm be used for this? If not, how should the form be created so that the JS fills in the fields, the fields are hidden and unchangeable by users, and it makes use of csrf_token?

This is all I have so far. There are a bunch of input fields that get filled automatically by the JS. The form|crispy generated by ModelForm doesn't get filled, even though the id is the same (field names in models.py are the same as Google's naming scheme). I don't understand how the last paragraph of the JS works, that's likely where I'm stuck.

Update: The following code is not giving a POST, why?

<!-- language: lang-js -->

$.ajax({
    type: 'POST',
    url: 'http://localhost:8000/place/new',
    dataType: 'json',
    data: {
        csrfmiddlewaretoken: '{{ csrf_token }}',
        address: 'test'
    },
    success: function (response, textStatus, error) {
        console.log('SUCCESS')
    },
    error: function (request, textStatus, error) {
        console.log('error')
        console.log(place)
    }
});
<!-- end snippet -->

<!-- language: lang-python -->

def placenew(request):
    if request.method == 'POST':
        test = request.POST.get('address')
        response_data = {}
        print (test)
        print ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
        return render(request, 'app/placenew.html', {'key':key})
    else:
        print ("not POST")
        return render(request, 'app/placenew.html', {'key':key})

<!-- end snippet -->

1 Answer 1

0

If you wanted to pass variables from the JS to django then you could look at posting an ajax request to your view and providing whatever data you want in the data attribute.

For example, I'm in the middle of doing exactly this using Knockout JS so I have this ajax request;

$.ajax({
    url: URLS.design,
    method: 'POST',
    data: {
        data: ko.mapping.toJSON(structure_data)
    },
    success: function (response, textStatus, error) {
        console.log('SUCCESS')
    },
    error: function (request, textStatus, error) {
        console.log('error')
    }
});

You could get the field values, variables or whatever else you wanted and pass them in the data attribute of $.ajax.

Alternatively you could setup fields in your ModelForm with the HiddenInput() widget so your javascript can populate them, without your user worrying about them. Then if they were populated correctly, you could just post the form & your data would be sent to the view.

To read up on Ajax, this looks like a great article; https://realpython.com/blog/python/django-and-ajax-form-submissions/

Essentially the url attribute would just be somewhere you've got your view setup like /myapp/myview/ and then in your view it's very similar to how you'd handle any normal POST request. For example, I'm currently doing this with the above bit of Javascript when it hits my view;

def get_forms(self, forms):
    data = None

    if self.request.method in ('POST', 'PUT'):

        if self.request.is_ajax():
            _json = self.request.POST.get('data')
            data = json.loads(_json)
        else:
            data = self.request.POST

Update

Well first of all when you're defining your URL, make sure you include a trailing slash or when it hits Django it'll get redirected. So you'll want url: '/place/new/'.

Also, your response from the server should return JSON if it's received an AJAX request. So you might do something like;

def placenew(request):
    if request.method == 'POST':
        test = request.POST.get('address')
        response_data = {}

        if request.is_ajax():
            return HttpResponse(
                json.dumps(response_data),
                content_type="application/json"
            )
        return render(
            request, 'app/placenew.html', {'key':key}
        )
    else:
        print ("not POST")
        return render(request, 'app/placenew.html', {'key':key})

Also, I'm assuming you've followed that tutorial and have your ajax call defined within a function which you trigger somehow when your form is submitted?

Sign up to request clarification or add additional context in comments.

11 Comments

I have zero experience with Ajax, where do I put the code and is there anything to install? As for the alternative, I'm trying that now and the id seems to match the one in the example, but it doesn't fill in. Edit: nevermind, apparently Django puts id_ in front of the id and that's probably the reason it doesn't work.
Yeah that's standard for django rendering forms. I've updated my answer with some more detail & a good link for an article on django & ajax.
I changed it to url: '/place/new/' and it didn't fix it. I did follow the tutorial as best I could, and I know it is being called because console.log('error') works and it also logs the correct information in place. I don't quite understand what's going on inside if request.is_ajax():, but I copied it in and it still prints not POST.
The not POST is printing as the first thing when I load the page, and no messages print after running the autocomplete. F12 shows the console.log('error'), so that means the AJAX isn't sending anything to the view?
@vandidant That's correct. The first time you load that page you're performing a GET request, not a POST. When you submit a form to that view with a method=post it'll send a POST request.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.