I am new to django, trying to use AJAX to move data from html to views.py via AJAX, something weird is happening, data is moving but the page is not changing, new page is not getting rendered.
HTML CODE
<div class="bodyclass">
{% csrf_token %}
{% for account in accounts %}
<div class="">
<div class="accountname">
<button onclick="submitform('{{ account}}')" class="btn btn-info accbtn " id="{{ account }}">{{account}}</button>
</div>
</div>
{% endfor %}
</div
JS Code
<script>
function submitform(accname){
alert(accname);
var csrf = document.getElementsByName('csrfmiddlewaretoken');
$.ajax({
type : 'POST',
url : 'accounts',
data:{
csrfmiddlewaretoken : csrf[0].value,
'accname': accname,
},
});
alert('bye');
}
</script>
views.py
def accounts(request):
if request.user.is_authenticated:
if request.method == 'GET':
if request.user.is_superuser:
account = AccountDescription.objects.all()
else:
account = UserAccount.objects.filter(user=request.user)
return render(request, 'accounts.html',{'accounts':account})
elif request.method == "POST":
print(request.POST)
print(request.POST.get('accname'))
return HttpResponseRedirect('/clientinfo')
else:
return HttpResponseRedirect('/login')
also the cmd screenshot
Kindly let me what wrong I am doing. also let me know if any more input is required.
Thanks in advance.
Read ajax return output on JS File
JS Code
$.ajax(
{
type:"POST",
url: "/checkonline",
data:{
//Pass CSRF & Data
},
success: function(data)
{
//Read Response Here
//redirect user to here using javascript
alert(data);
}
})
views.py
//Example for Return Response in JSON Format
from django.http import JsonResponse
def accounts(request):
return JsonResponse(list({"redirect_user"}) , safe=False)
Related
It appears I have come across very strange behavior. I am building a ReactJS+Django 3.0 application. Here is the problem...
I have a <form onSubmit={handleSubmit}> that wraps the form on the frontend.
const handleSubmit = (e) => {
e.preventDefault();
axios.post(paths.login, qs.stringify({
email: emailVal,
password: passwordVal
}));
}
This works perfectly fine in sending data to the Django view! But when I try to then pass context variable through the Django view, it just fails completely. Meaning,
def login(request):
data = {}
'''
Handle Logging in
'''
if request.method == 'POST':
login_form = forms.LoginForm(request.POST)
if login_form.is_valid():
user = login_form.authenticate_user()
#login(request, user)
return redirect('home')
else:
data['errorMessage'] = ''
for field, errors in login_form.errors.items():
for error in errors:
data['errorMessage'] += error
print(data)
return render(request, 'index.html', context=data)
Given this, the data dictionary will be empty at first, but even when the print(data) shows that the data dictionary is populated, the context data that is sent to the index.html file is still empty.
WHY MIGHT THIS BE? I've been stuck on this forever.
I can work around this if I just use form submission instead of axios like this: <form method='POST'> However, I need to use axios. SOS
You can also use the Django messages framework for this, which might be a better option (assuming you are re-rendering the page after POST):
from django.contrib import messages
def login(request):
data = {}
'''
Handle Logging in
'''
if request.method == 'POST':
login_form = forms.LoginForm(request.POST)
if login_form.is_valid():
user = login_form.authenticate_user()
#login(request, user)
return redirect('home')
else:
error_message = ''
for field, errors in login_form.errors.items():
for error in errors:
error_message += error
messages.add_message(request, messages.ERROR, error_message)
return render(request, 'index.html')
Then in your template (this is an example using Bootstrap, but you can modify it to fit your needs):
{% if messages %}
{% for message in messages %}
{% if message.tags == 'error' %}
<div class="alert alert-danger alert-with-icon alert-dismissible fade show" role="alert">
{% else %}
<div class="alert alert-{{ message.tags }} alert-with-icon alert-dismissible fade show" role="alert">
{% endif %}
{{ message|safe }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endfor %}
{% endif %}
If you are sending data back as an AJAX JSON response instead:
from django.http import JsonResponse
def login(request):
data = {}
'''
Handle Logging in
'''
if request.method == 'POST':
login_form = forms.LoginForm(request.POST)
if login_form.is_valid():
user = login_form.authenticate_user()
#login(request, user)
return redirect('home')
else:
error_message = ''
for field, errors in login_form.errors.items():
for error in errors:
error_message += error
data['error_message'] = error_message
return JsonResponse(data)
else:
return render(request, 'index.html')
In your Axios code:
const handleSubmit = (e) => {
e.preventDefault();
axios.post(paths.login, qs.stringify({
email: emailVal,
password: passwordVal
}).then((response) => {
//do something with JSON response
}, (error) => {
//do something with JSON response
});
});
I am trying to implement a search function to search for users of my blog. In my base.html I have my navbar and within the navbar I have the following search form:
<form class="form-inline" method="POST">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">#</span>
</div>
{% csrf_token %}
<input id="user_search" type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
<ul class="list-group" id="results"></ul>
</div>
</form>
My ajax code looks as follows:
$('#user_search').keyup(function(){
$.ajax({
type: 'POST',
url: "{% url 'user-search' %}",
data: $(this).serialize(),
dataType: 'json',
success: function(response){
$('#results').html(response['form']);
console.log($('.profile-section').html(response['form']));
},
error: function(rs, e){
console.log(rs.responseText);
},
});
});
and my views.py search view looks as follows:
def user_search(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
users = User.objects.filter(username__icontains=search_text)
context = {
'users': users,
}
if request.is_ajax():
html = render_to_string('feed/user_search.html', context, request=request)
return JsonResponse({'form': html})
and the relevant part of my urls.py looks like this:
path('search/', login_required(views.user_search), name="user-search"),
When entering data in the input field I am getting a 403 HTTP error that says I am not using the csrf_token correctly, however I have included it as I did it before and it worked the other times before...
Any idea how I can solve the 403 error?
I had to change the JS part like this:
$(document).on('keyup', '.user-search-form', function(event){
event.preventDefault();
var input = $('#user_search').val();
console.log(input);
if (input.length > 2) {
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'json',
success: function(response){
$('#results').html(response['form']);
console.log($('#results').html(response['form']));
},
error: function(rs, e){
console.log(rs.responseText);
},
});
}
else {
$('#results').empty();
}
});
and the python part in the views.py like that:
def user_search(request):
if request.method == 'POST':
search_text = request.POST.get('input')
users = User.objects.filter(username__icontains=search_text)
context = {
'users': users,
}
if request.is_ajax():
html = render_to_string('feed/user_search.html', context, request=request)
return JsonResponse({'form': html})
and now the search works!
i tru use ajax with django.
There are 2 forms. the first with the name and mail. and a quick form with a confirmation code that comes in the mail.
views.py
def get_name(request):
if request.method == 'POST':
user_code = generate_code(8)
subject = 'code'
message = user_code
form = NameForm(request.POST)
if form.is_valid():
Registration.objects.create(fio=request.POST['fio'],mail=request.POST['mail'])
send_mail(subject, message,settings.EMAIL_HOST_USER,[mail],fail_silently=False)
return JsonResponse({ 'form1': render_to_string( 'registers/endreg.html', {'form': NameForm1()},request=request ) })
else:
form = NameForm()
return render(request, 'registers/detail.html', {'form': form})
template (detail.html)
<form action="" method="post" autocomplete="off" id="my_form">
{% csrf_token %}
<div class="contact-form" >
<h1>{%trans 'Registers' %}</h1>
<div class="txtb">{{form.fio.label}} {{form.fio}}{{form.fio.help_text}}</div>
<div class="txtb">{{form.phone.label}} {{form.phone}}{{form.phone.help_text}}</div>
<input type="submit" value="{%trans 'send' %}" class="btn" id="btn">
</div>
</form>
I am hanging an event to submit this form
$(document).ready(function()
{ $("#my_form").submit(function(event)
{ event.preventDefault();
$this = $(this);
$.ajax({
type: "POST",
data: $this.serialize(),
success: function(data)
{ console.log(data);
var parent=$("#my_form").parent();
parent.html(data.form1);
},
error: function(data)
{ console.log(data);
$this.html(data);
}
});
});
});
ajax request works and get my 2 form (endreg.html)
<form action="endreg/" method="post" autocomplete="off" id="my_form2">
{% csrf_token %}
<div class="verification" >
<div class="ver">
{{form}}
</div>
<input type="submit" value="{%trans 'send' %}" class="btn1" >
</div>
</form>
views.py
def endreg(request):
if request.method == 'POST':
form = NameForm1(request.POST)
if form.is_valid():
code_use = form.cleaned_data.get("key")
try:
user = Registration.objects.get(code=code_use)
user.verification = True
user.save()
JsonResponse({'message': 'thanks.'})
except:
JsonResponse({'error': 'erorr.'})
else:
form = NameForm1()
return render(request, 'registers/endreg.html', {'form': form})
and 2nd ajax.
$(document).ready(function()
{ $("#my_form2").submit(function(event)
{ event.preventDefault();
$this = $(this);
$.ajax({
type: "POST",
data: $this.serialize(),
success: function(data)
{ console.log(data);
},
error: function(data)
{ console.log(data);
}
});
});
});
Now the question. why when I enter the code in the second form, the code is applied and a redirect to localhost:8000/endreg occurs with json .
Looks like your form is not valid, thats why it is loading the same page with the entered data. You should handle the failure condition for form.is_valid(). And also don't add the blank exception block for handling exceptions.
def endreg(request):
if request.method == 'POST':
form = NameForm1(request.POST)
if form.is_valid():
code_use = form.cleaned_data.get("key")
try:
user = Registration.objects.get(code=code_use)
user.verification = True
user.save()
messages.warning(request, u'thanks.')
except Registration.DoesNotExist as e: # Handling Exception for get()
print("NOT FOUND", e)
messages.warning(request, u'error.')
else: # if form is not valid
messages.warning(request, u'not valid.')
form = NameForm1() # reset the form
else:
form = NameForm1()
return render(request, 'registers/endreg.html', {'form': form})
In your HTML, you can render {{ form.errors }} as well.
I'm using Django for an app that allows you to search and save recipes. I'm trying to have a form on a search results page that allows you to click 'save' and creates an object to the database without reloading the page. In the current setup when I click on the 'save' button for the form with id="add_form" I get redirected to a new url (add/) even though I've included preventDefault().
I thought this was due to me including the form action={%url 'add' %} however, I've tried removing the form action but that gave me a multiValueDictKeyError for raw_input = request.POST['ingredients'] so I thought it was calling the incorrect view function views.recipes instead of views.add. I've read some other ajax guides that explicitly state a form action so I thought that would help with the incorrect view function being called.
views.py
def recipes(request):
if request.method == 'POST':
# check for dietary restrictions
restrictions = request.POST.getlist('restrictions')
# format input ingredients
raw_input = request.POST['ingredients']
...
return render(request, 'recipes/recipes.html', {'results': results})
else:
return render(request, 'recipes/recipes.html', {'error': 'Please search for a recipe'})
#csrf_protect
def add(request):
if request.method == 'POST':
title = request.POST['title']
image = request.POST['image']
source = request.POST['source']
user = request.user
try:
recipe = Recipe.objects.get(image=image, title=title, source=source)
except ObjectDoesNotExist:
recipe = Recipe.objects.create(image=image, title=title, source=source)
finally:
recipe.users.add(user)
recipe.save()
return JsonResponse({'success': True})
else:
return JsonResponse({'success': False})
urls.py
urlpatterns = [
path('add/', views.add, name='add'),
path('', views.recipes, name='recipes'),
]
html file
{% block content %}
...
{% if user.is_authenticated %}
<form action="{% url 'add' %}" id="add_form" method="POST">
{% csrf_token %}
<input type="hidden" id="image" name="image" value="{{ result.image }}">
<input type="hidden" id="title" name="title" value="{{ result.title }}">
<input type="hidden" id="source" name="source" value="{{ result.source }}">
<button type="submit" name="recipe" class="btn btn-sm btn-outline-secondary">Save</button>
</form>
{% endif %}
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function() {
$("#add_form").on('submit', function(e) {
e.preventDefault();
console.log( "form submitted");
$.ajax({
type:'POST',
async: 'false',
cache: 'false',
url:'{% url 'add' %}',
data:{
image:$('#image').val(),
title:$('#title').val(),
source:$('#source').val(),
},
success:function(){
alert("Saved Recipe")
}
})
})
})
</script>
I'm expecting any clicks to the save button to stay on the same page without a reload and to call views.add which will save/create an object to the database
Change the url to $(this).attr('action'). It will automatically get the url from the form instead of explicitly defining it again while making ajax call.
$.ajax({
type:'POST',
async: 'false',
cache: 'false',
url: $(this).attr('action'),,
data:{
image:$('#image').val(),
title:$('#title').val(),
source:$('#source').val(),
},
success:function(){
alert("Saved Recipe")
}
})
I am using a django form to update some details. once the save changes is clicked the ajax call is made, view executed, ajax response sent, success code executed n the page reloads again. n on reload as form is no longer valid, the else part of from.is_valid() is executed.
if form.is_valid:
#do something
return HttpResponse(simplejson.dumps(response), mimetype='application/json')
else:
#do something
return render_to_response('ts.html', {'form': form}, context_instance = RequestContext(request))
I want to avoid the page reload on the successful form submission and jus return ajax response. How can achieve that?
I have changed my code and here is the view, template and jquery.
if request.POST:
if form.valid():
if credentials.correct():
resp = {'success': True}
return HttpResponse(simplejson.dumps(resp), mimetype='application/json')
else:
resp = {'success': False}
return HttpResponse(simplejson.dumps(resp), mimetype='application/json')
else:
print "error in form"
return render(request, 'manage_accounts.html', {'creds': creds, 'form': form})
else:
form = SomeForm()
return render(request, 'manage_accounts.html', {'creds': creds, 'form': form})
Template
<form action="/accounts/" method="POST" id="bitlychangeform">
<div id="ajaxwrapper">
{% csrf_token %}
{{ form.non_field_errors }}
<!--{% include "Change_bitly_form.html" %}-->
{{ form.as_p }}
<div class="clearfix">
<label></label>
<div class="input" style="float:right">
<input type="submit" id="save" value="Save Changes" class="btn btn-primary "/>
</div>
</div>
</div>
</form>
Jquery:
$(function(){
var form = $('#bitlychangeform');
form.submit(function(e) {
jQuery("#save").attr('disabled', true)
jQuery("#ajaxwrapper").load(
form.attr('action') + ' #ajaxwrapper',
form.serializeArray(),
function(data) {
jQuery("#save").attr('disabled', false)
alert(data);
});
return false;
e.preventDefault();
});
});
The page reload doesn't occur when i use Django form as {{ form.as_p }} but when i use a "custom template for form with fields as password char fields with ** and editable only after one clicks edit button", the form.valid() returns false.
I require that the django form functions as my custom template for form as i desire. Can anyone guide me.
You can handle this in your JavaScript by returning false on submission of form.
form.submit(){
#do something
#make AJAX call
#do something
return false;
}
I would guess you didn't override the default form submission behavior on the front end, and you are submitting your form normally.
Make sure that you supress the default behavior of form submission.
This page
provides a great example under templates/contact/form.html