Django is not taking GET input in AJAX call - python

I am trying to take username input and return in ajax call whether the username is taken or not in Django. But the method in DJango is not taking the input. I am sharing the code here.
URL.py
url(r'^search_username/$', user.views.search_product, name="search_username"),
script + HTML
{% load staticfiles %}
{% block content %}
<form method="post">
{% csrf_token %}
<input name="search" id="search" type="text"/>
<button type="submit">Sign up</button>
</form>
{% endblock %}
$("#search").change(function () {
var username = $(this).val();
$.ajax({
url: '/search_username/',
data: {
'username': username
},
dataType: 'json',
error: function(){
alert('failure');
},
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
Views.py
def search_username(request):
print('Entered into search')
username = request.GET.get('search', None)
print(username)
data = {
'is_taken': allproductlist.objects.filter(product_name_english__iexact=username).exists()
}
return JsonResponse(data)
The problem is it prints Entered into search.But when I print username it shows NOne. Can anyone please specify what is happening ?

Your Ajax is sending the data as "username" but your Python is looking for "search".

you are sending username in ajax request but you are getting search in views.py.
you can Update your ajax code:
$("#search").change(function () {
var username = $(this).val();
$.ajax({
url: '/search_username/',
data: {
'search': username
},
dataType: 'json',
error: function(){
alert('failure');
},
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
2nd way is that you can change in views.py.
username = request.GET.get('username', None)

Related

How to send data to the view in Flask using AJAX?

Please help...
I am trying to upload a csv or excel file, and using an Ajax call trying to send it to Flask along with an integer.
HTML Form:
<form id="testFileForm" method="POST" action="{{ url_for('auto') }}" enctype="multipart/form-data">
{{ fileUploadForm.csrf_token }}
<label class="connect choosefile setInput config-button-size " >
<i class="fa fa-file" aria-hidden="true"></i>
<span id="testFileLabel">Choose Test Data</span>
{{ fileUploadForm.file(class="input1 btn btn-primary", id="testFile") }}
</label>
<label class="form-label" style="padding-left:10px ;">
<input class="btn btn-primary config-button-size" id="testFilebtn" type="submit" value="Process">
</label>
</form>
Ajax Call:
$('#testFilebtn').click(function() {
var file = document.getElementById("testFile").files[0];
alert(file)
var data = {
file: file,
id : 1
}
alert('file loaded')
$.ajax({
data: data,
type: "POST",
url: "auto",
"Content-Type": 'application/json',
dataType: 'json',
success: function(response) {
alert(response)
},
});
});
View:
#app.route('/auto', methods=['POST', 'GET'])
#login_required
def auto(dataset_id=None):
fileUploadForm = FileUploadForm()
if request.method=='POST' and fileUploadForm.validate_on_submit():
try:
file = request.files['file']
id = request.form['id']
print('id')
print(id)
except UploadNotAllowed:
return redirect(url_for("auto"))
# return redirect(url_for("auto"))
return "te"
I get error while retrieving the id, which indicates I am also not receiving file from ajax call.
Error:
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'id'
I am new to Ajax calls, some help would highly be appreciated...
I believe you could do it like this :
var fd = new FormData($('#testFileForm')[0]);
fd.append( 'id', 1 );
$.ajax({
url: 'http://example.com/',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string.
See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.

How do I toggle boolean field

I am working on a project where user have his own profile, I want to create a BooleanField on model so that user can set profile privacy, private or public. I have added a BooleanField to modal (is_private). Also i have a toggle switch on template but i do not know how to go with it with Django. I want when a user click on switch boolean field is true (private), when user click again on switch boolean field is false (public). Jquery maybe needed as well.
Model:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True)
is_private = models.BooleanField(default=False)
Views:
def profile_edit_view(request):
p = Profile.objects.filter(user=request.user).order_by('-id')
context = {'p':p}
return render(request, 'profile_edit.html', context)
urls:
path('account/edit/', profile_edit_view, name ='profile-edit'),
Profile Edit Template:
<form method="POST" name="is_private">
{% csrf_token %}
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="customSwitches" name="is_private">
<label class="custom-control-label" for="customSwitches">Private Account</label>
</div>
</form>
<p class="text-muted font-weight-normal font-small">
When your account is private, only people you approve can see your photos and videows on Pixmate. Your existing followers won't be affected.
</p>
In template file change the input tag as shown
<!-- Mark the checkbox as checked or not by is_private -->
<input type="checkbox" class="custom-control-input" id="customSwitches" {% if p.is_private %}checked{% endif %}>
In that same template file add this script
<script type="text/javascript">
$(document).ready(function() {
// send request to change the is_private state on customSwitches toggle
$("#customSwitches").on("change", function() {
$.ajax({
url: "{% url 'change_privacy' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
is_private: this.checked // true if checked else false
},
type: "POST",
dataType : "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function(data) {
console.log(data);
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
.always(function() {
console.log('[Done]');
})
})
});
</script>
Add a new path in your urls file of the app which binds to a view. Say: a function named change_privacy() in your views
path('changeprivacy', change_privacy, name="change_privacy"),
In views file add a new function. You need to import JsonResponse
from django.http import JsonResponse
def change_privacy(request):
if request.is_ajax() and request.method=='POST':
profile = Profile.objects.get(user=request.user)
profile.is_private = True if request.POST.get('is_private') == 'true' else False
profile.save()
data = {'status':'success', 'is_private':profile.is_private}
return JsonResponse(data, status=200)
else:
data = {'status':'error'}
return JsonResponse(data, status=400)
Here is how to do it with Ajax.
First include jQuery:
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
Ajax setup, you need to include a CSRF token (or make decorate your view with #csrf_exempt). Relevant section in the django documentation. If you don't include the CSRF token in your request you will get 403 Forbidden.
<script type="text/javascript">
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
</script>
Then make the Ajax request:
<script type="text/javascript">
$("document").ready(function () {
$("#customSwitches").change(function () {
$.ajax({
type: "POST",
headers: {
"X-CSRFToken": csrftoken
},
url: {% url 'privacy' %},
data: {
"enabled": this.checked,
},
success: function (data) {
console.log(data);
},
error: function (data, msg) {
console.log("ERROR", data, msg);
}
});
})
});
</script>
Adjust the url to work with your project and don't forget to include the CSRF token in the header.
Then you can get the value of the checkbox in your view and update the value for your user:
def privacy_view(request):
if request.is_ajax():
enabled = request.POST["enabled"]
profile = Profile.objects.get_or_create(user=request.user)
profile.is_private = enabled
profile.save()
return render(request, "privacy.html")

How to populate a django form in a POST request with data from an ajax call?

I'm sending form data via an ajax call after user hits submit button and then handling this request in my views, but the form is empty. How can I populate the form?
This is my code:
My JS file:
var csrftoken = getCookie('csrftoken'); //getCookie is a csrf_token generator
var form = $(this).closest('form')
$.ajax({
url: form.attr("action"),
data: { // if I change this line to data: form.serialize(), it works fine!
csrfmiddlewaretoken : csrftoken,
form: form.serialize(),
},
type: form.attr("method"),
dataType: 'json',
success: function (data)
{
//Do a bunch of stuff here
}
})
My views:
def task_edit(request, pk):
task = get_object_or_404(Task, pk=pk)
if request.method == 'POST':
task_form = NewTaskForm(request.POST) # This is empty!
else:
task_form = NewTaskForm(instance=task) # This for populating the edit modal, works fine!
I'm not doing the data: form.serialize() because I need to send additional data with the ajax request. How do I get this working?
You can write as below:-
$form_data = $("#idofform").serialize();
And then in ajax
data : $form_data+'&key=value',
You can use services like https://www.formkeep.com to capture form data using AJAX.
This may be a good idea if you are already using a JavaScript framework, you want to add validation logic, or you don't want to redirect the user after they submit the form.
You can submit to FormKeep using a standard AJAX request. To ensure the request does not cause a redirect, be sure to set the Accept header to application/javascript.
Given the following form:
<form id="newsletter-signup" action="http://formkeep.com/f/exampletoken" method="POST" accept-charset="UTF-8">
<input type="hidden" name="utf8" value="✓">
<input name="email" type="email">
<input value="Submit" type="submit">
</form>
Here's an example of how to submit a form with jQuery:
$(function() {
$('#newsletter-signup').submit(function(event) {
event.preventDefault();
var formEl = $(this);
var submitButton = $('input[type=submit]', formEl);
$.ajax({
type: 'POST',
url: formEl.prop('action'),
accept: {
javascript: 'application/javascript'
},
data: formEl.serialize(),
beforeSend: function() {
submitButton.prop('disabled', 'disabled');
}
}).done(function(data) {
submitButton.prop('disabled', false);
});
});
});
That's it. Once your data is securely captured in FormKeep you can easily store it, manage it or connect it with 1000s of other systems like Google Docs and Hubspot and Mailchimp.

Django ajax redirecting on form submission

I'm trying to return data with an ajax request on a form submission. My goal was too use two views, one too handle the template loading and the other to handle the POST request from the form. In the current state, the form is redirecting to the JSON that is in the callback. That makes sense as it's for the form action url is pointing, however, i want to just pass the data to the current page and not reload the page or be redirected to another page.
Here is the code:
user.html
<form action="{% url 'ajax-user-post' %}" method="post">
{% csrf_token %}
{% for user in users %}
<input type="submit" name="name" value="{{ user }}">
{% endfor %}
views.py
def ajax_user(request):
# get some data..
if request.METHOD == 'POST':
user = request.POST['user']
user_data = User.objects.get(user=user)
data = {'user_data': user_data}
return JsonResponse(data)
def user(request):
return render(request, 'user.html', context)
urls.py
url(r'^user/', user, name="user"),
url(r'^ajax/user/', ajax_user, name="ajax-user-post")
.js
$('form').on('submit', function(){
var name = // the name of the user selected
$.ajax({
type: "POST",
dataType: "json",
url: 'ajax/user/',
data: { 'csrfmiddlewaretoken': csrftoken, 'name': name, 'form': $form.serialize() },
success:function(data) {
// hide the current data
console.log(data);
displayUserData(data)
}
})
});
Thanks for the help in advance!
i want to just pass the data to the current page and not reload the page or be redirected to another page.
That means you need to stop the form submission event with the event.preventDefault() call.
Hence, change this line from:
$('form').on('submit', function(){
to to following two:
$('form').on('submit', function(e){
e.preventDefault();

Forbidden (CSRF token missing or incorrect.)

I've searched through similar questions, but nothing seems relevant to my situation.
Why does this code work fine:
<form action="/signup/" method="post">
{% csrf_token %}
[FORM]
</form>
but
<form id="signup-form">
{% csrf_token %}
[FORM]
</form>
<script type="text/javascript">
$(function() {
$(".submit-signup").on("click", function() {
var user = $("#signup_form").serialize();
console.log(user);
$.post("/signup/", user, function() {
});
});
});
</script>
not work?
Here is signup in views.py:
#requires_csrf_token
def signup(request):
[STUFF]
return render(request, 'signup.html', {[STUFF}})
What else can I provide that would help? Basically I am trying to take a page and turn it into a modal that does the same thing.
Thanks!
you are doing an ajax post call for which you need to give csrf token also:
$.post("/signup/", {
user: user,
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function() {
// success todo
}, function(){
// fail todo
});

Categories

Resources