Can I send .json with data like (login,password from input html) to django who download this file and check login/password? Then I want return results by django to js,jquery. I dont wan use forms-django in form-html and dont want change urls.
code html:
<form id='login_form' action="" method="POST">
{% csrf_token %}
<div id='Login_form'>
<p>Login: </p> <input type="text" onblur="CheckEmptyElements();" id="flogin">
<p>Password: </p> <input type="password" onblur="CheckEmptyElements();" id="lpass">
<div id="butt_form">
<button type="button" class="butt_forme" id="button" onclick="CheckBeforeSend();">Enter</button>
</div>
</div>
</form>
code js:
var LoginInput = document.getElementById('flogin');
if(LoginInput.value.match(/^[a-zA-Z]+['.']+[a-zA-Z]+[0-9]+$/) == null)
{
if(document.getElementById('Windows').childElementCount > 2)
{
document.getElementById('Windows').children[0].remove();
}
AddPicture("paperJsConn");
}
else // <--- Check login/pass in base django
{
document.getElementById("button").type = "submit";
$.ajax({
type:"POST",
url: '',
data: {
"login":
"password":
},
success: function(response){
//animation and change site if correct login/pass or reloaded site.
}
});
}
and views.py:
def Logget(request):
if request.is_ajax and request.method == "POST":
//take login from json and check in base by loop
//if find check password
if: // correct
// return .json or message that is correct.
else:
// return .json or message that is not correct.
return render(request, 'index.html')
Someone help please?
Related
I'm trying to perform a OTP-based login in my project. So I have a form with email and password field in the login form and when I submit it through AJAX request I check for the email and password in the database, if the values are correct then I will send an OTP through email and display a new OTP field on the same page for Entering the OTP for verifications.
Till now everything is working fine but after entering the OTP when I try to re-submit the form, I got an error csrf_token is not valid. As far as I know csrf_token is only generated on page refresh or page load but in my case the first csrf_token that was generated on page load was used in first post request.
So now how can I send the second post request with same csrf_token or can I generate the new csrf_token.
Code snippets are as follows:
<form id="loginForm" method="post" action="send_otp">
<div class="col-12">
<label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Email</label>
<input id="email" type="text" name="email" placeholder="Name">
</div>
<div class="col-12">
<label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Password</label>
<input id="password" type="password" name="password" placeholder="Password">
</div>
<div id="otp_field" class="col-12">
</div>
<div class="col-12">
<button type="submit" name="submit" id="send_otp" class="button -md -green-1 text-dark-1 fw-500 w-1/1">Login</button>
</div>
</form>
Sending the request and adding the OTP input field on success through Ajax:
$("#loginForm").submit(function(event) {
/* stop form from submitting normally */
event.preventDefault();
/* get the action attribute from the <form action=""> element */
var $form = $(this),
url = $form.attr('action');
/* Send the data using post with element id name and name2*/
var posting = $.post(url, {
"csrfmiddlewaretoken":"{{ csrf_token }}",//$('input[name="csrfmiddlewaretoken"]').val(),
"email": $('#email').val(),
"pass": $('#password').val()
});
/* Alerts the results */
posting.done(function(data) {
$('#email'). attr('disabled','disabled');
$('#password'). attr('disabled','disabled');
$('#otp_field').append('<label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Enter OTP</label><input id="otp" type="text" name="otp" placeholder="Enter OTP">')
});
posting.fail(function() {
});
});
How can I achieve it?
Add the javascript from this django-doc to your page.
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');
Pass csrfmiddlewaretoken:getCookie('csrftoken')
{% csrf_token %} returns an input tag, which you don't want, and have misspelled.
From another question:
Try adding the #csrf_protect decorator just before your login function.
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def login(request):
csrfContext = RequestContext(request)
return render_to_response('foo.html', csrfContext)
If the form is not in foo.html then you need to add the #csrf_protect method to the view function that is generating it.
https://stackoverflow.com/a/12731412/18020941
I have a django template with two forms in it. When the first form is submitted, an ajax function is triggered and the second form is displayed on the page. When the second form is submitted, the ajax function linked to that form does not seem to work.
For testing purposes, I tried to submit the second form before submitting the first form, and the ajax function works as expected. How do I make multiple ajax functions work correctly one after the other?
This is my template
<div class="form_container">
<div class="form">
<form action="{% url 'process_url' %}" method="post" id="youtube_link_form">
{% csrf_token %}
<div class="input-group mb-3">
<input type="text" class="form-control youtube_link_input"
placeholder="Put the youtube link or video id" aria-label="youtube_submit_input"
aria-describedby="youtube_submit_button" name="youtube_submit_input">
<button class="btn youtube_submit_button" type="submit" id="youtube_submit_button">Submit</button>
</div>
</form>
</div>
</div>
<div class="user_target_select">
<div class="target_buttons d-flex justify-content-between">
<form method="get" action="{% url 'user_select_positive' %}" id="positive_user_select_form">
<input type="hidden" id="positive_user_select_input" name="positive_user_select_input">
<button class="target_button btn btn-outline-success" id="user_select_positive" type="submit"
data-bs-toggle="modal" data-bs-target="#thank_model">Positive</button>
</form>
</div>
</div>
Here, user_target_select div is hidden by default. When the first form is submitted, the div is displayed.
This is my js file
function youtube_link_form_submit(event) {
event.preventDefault();
var data = new FormData($('#youtube_link_form').get(0));
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: data,
cache: false,
processData: false,
contentType: false,
success: function (data) {
$('#status').append(data['status'])
$('.user_target_select').css('display', 'block');
if (data['status'] == 'video parsed successfully') {
console.log('data submitted successfully')
}
}
})
return false;
}
function positive_user_select_form_submit(event) {
event.preventDefault();
var data = $(this).serialize();
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: data,
cache: false,
processData: false,
contentType: false,
success: function (data) {
console.log(data)
$('.user_target_select').css('display', 'none');
}
})
return false;
}
// trigger the above functions on form submit
$(function () {
$('#youtube_link_form').submit(youtube_link_form_submit);
})
$(function () {
$('#positive_user_select_form').submit(positive_user_select_form_submit);
})
Currently when the second form is submitted the ajax function is not called. I know this because the event.preventDefault() is not working and the JsonResponse from the django view is executed on a new page. The URL also changes. If I try to submit the second form without submitting the first form, the function works as expected.
I am following by this tutorial on how to get live updates on django without refreshing the page.
The tutorial uses flasks render_template to get the html rendered which is then injected to a page section.
I am trying to do the same in Django, But django just directly renders it in the browser... I don't want that. I just want django to send the rendered html response to AJAX which could then inject that to a section on my live page.
Here is the code :
views.py
class ManageView(LoginRequiredMixin, View):
template_name = "dashboard/manage.html"
context = {}
def get(self, request, app_id, folder_id=None):
app = App.objects.get(pk=int(app_id))
self.context["app"] = app
if folder_id:
try:
self.context["folder"] = Folder.objects.get(id=folder_id)
except:
self.context["folder"] = app.folder
else:
self.context["folder"] = app.folder
return render(request, self.template_name, self.context)
def post(self, request, app_id, folder_id=None):
try:
files = request.FILES.getlist('files_to_upload')
folder_name = request.POST.get("folder")
master = request.POST.get("master")
if master:
master = Folder.objects.get(id=master)
if folder_name:
Folder.objects.create(name=folder_name, owner=request.user.customer, folder=master)
if files:
for file in files:
if file.size < settings.MAX_FILE_SIZE:
File.objects.create(folder=master, item=file, name=file.name, size=file.size)
app = App.objects.get(pk=int(app_id))
self.context["app"] = app
if folder_id:
try:
self.context["folder"] = Folder.objects.get(id=folder_id)
except:
self.context["folder"] = app.folder
else:
self.context["folder"] = app.folder
return render(request, 'dashboard/filesection.html', self.context)
except DatabaseError:
return render(request, "dashboard/index.html", self.context)
urls.py
urlpatterns = [ url(r'^manage/(?P<app_id>[0-9]+)/(?P<folder_id>.+)', test, name='browse'), ]
dashboard/manage.html
<div class="modal-body">
<form id="app-launch" enctype="multipart/form-data" method="post">
{% csrf_token %}
<div class="form-row">
<div class="input-group mb-3">
<div class="custom-file">
<input type="hidden" value="{{ folder.id }}" name="master">
<input type="hidden" value="{{ app.id }}" name="file_app_id">
<input type="file" class="custom-file-input" name="files_to_upload" id="file_upload" accept=".py,.js,.json,.txt,.css,.html,.pdf,.htm,.doc,.docx,.log,.ppt,.pptx" multiple>
<label class="custom-file-label" for="inputGroupFile02">Choose file</label>
</div>
<div class="input-group-append">
<button class="input-group-text btn btn-primary" id="">Upload</button>
<button class="input-group-text btn btn-primary fileButton" id="">Upload</button>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger" data-dismiss="modal">Cancel</button>
</div>
</div>
app.js AJAX calls
$(document).ready(function() {
$(document).on('click','fileButton', function(e) {
e.preventDefault()
// const axios = require('axios');
var formData = new FormData();
var ins = document.getElementById('file_upload').files.length;
for (var x = 0; x < ins; x++) {
formData.append("files_to_upload", document.getElementById('file_upload').files[x]);
}
const csrftoken = getCookie('csrftoken');
var app_id = $('input[name="file_app_id"]').val();
var folder_id = $('input[name="master"]').val();
formData.append('master', folder_id);
req = $.ajax({
type: 'POST',
url: `/manage/${app_id}/${folder_id}`,
data: formData,
processData: false,
contentType: false,
headers: {
"X-CSRFToken": csrftoken,
}
});
req.done(function (data) {
$('#refreshSection').html(data)
})
});
});
AJAX POST and everything works, it just that the django is refreshing and rendering that section template on the browser which i don't want.
[Solved]
Its was a mistake from my side. I missed e.preventDefault()
which is really dumb.
I want to Ajax feature for the like button in my blog. I have implemented like feature first, it was working as expected(reloads page after clicking like button). Then, i want to implement Ajax so the page should not reload after clicking like button. But, it is not working as expected.
views.py:
def like_post(request):
user = request.user
if request.method == 'POST':
post_id = request.POST.get('id')
post_obj = get_object_or_404(Post, id=post_id)
if user in post_obj.liked.all():
post_obj.liked.remove(user)
else:
post_obj.liked.add(user)
like, created = Like.objects.get_or_create(user=user, post_id=post_id)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
if request.is_ajax():
post = Post.objects.all()
context={
'post': post
}
html = render_to_string('blog/like_section.html', context, request=request)
return JsonResponse({'form': html})
Jquery in base.html:
<script src="https://code.jquery.com/jquery-3.1.1.min.js">
<script type="text/javascript">
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault();
console.log("hello")
var pk = $(this).attr('value');
$.ajax({
type : 'POST',
url : {% url 'like-post' %},
data : {'id' : pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType : 'json',
success : function(response){
$('#like-section').html(response['form'])
console.log($('#like-section').html(response['form']));
},
error : function(rs, e){
console.log(rs.responseText);
},
});
});
});
</script>
like_section.html:
<form action="{% url 'like-post' %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_id" value="{{ post.id }}">
{% if user not in post.liked.all %}
<button id="like" class="btn btn-outline-info mb-4" type="submit">Like</button>
{% else %}
<button id="like" class="btn btn-info mb-4" type="submit">Unlike</button>
{% endif %}
</form>
urls.py:
path('likes/', views.like_post, name='like-post'),
It returns 404 with No Post matches the given query. My observation is, it looks it is not detecting Jquery part because if I replace 'id' with 'post_id' in request.POST.get('id') & return redirect under request.method == 'POST', it works like my previous version(Reloads page if I hit like button). So the control never goes into request.is_ajax() loop, How do I make Django to use Ajax?
I want to display an error screen for a new user who wants to retrieve a user name already taken using Ajax, but the project continues to run as if Ajax did not exist and django gives its own error.
how can i fix this problem ?
Thanks for help :):):)
...................................................................
register.html
{% extends "layout.html"%}
{% load crispy_forms_tags %}
{% block body %}
<script>
$("#id_username").change(function () {
var username = $(this).val();
$.ajax({
url: '/ajax/validate_username/',
data: {
'username': username
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
</script>
<body style = background-color:midnightblue;color:White;>
<div class="row">
<div class="col-md-6 offset-md-3">
<h3>Register</h3>
<hr style="background:white;">
<form method="post">
{% csrf_token %}
{{form|crispy}}
<br>
<button type="submit" class ="btn btn-danger">Register</button>
</form>
</div>
</div>
</body>
{% endblock body %}
page source
<script>
$("#id_username").change(function () {
var username = $(this).val();
$.ajax({
url: '/ajax/validate_username/',
data: {
'username': username
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
</script>
<div class="">
<input type="text" name="username" required class="textinput textInput form-control" id="id_username">
</div>
views.py
def validate_username(request):
username = request.GET.get('username')
data = {
'is_taken' :p User.objects.filter(username__iexact=username).exist()
}
return JsonResponse(data)
urls.py
urlpatterns = [
path('login/',views.loginUser,name = "login"),
path('register/',views.register,name = "register"),
path('logout/',views.logoutUser,name = "logout"),
path('panel/<str:username>',views.userPanel,name="userPanel"),
path('ajax/validate_username/',views.validate_username,name="validate_username")
]