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")
]
Related
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?
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?
I am trying to add ajax on the delete button of my blog, I want to update the page without reloading it when I delete an article, but I am getting this error when I use ajax and I don't understand what's going wrong.
Reverse for 'article_effacer' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['article/delete/(?P<slug>[-\\w\\d]+)/$']
I am turning myself to you because I'm having a hard time resolving this issue, so here is the code.
views.py
def article_effacer(request, slug):
if request.user.is_authenticated():
user = request.user
article = Article.objects.filter(slug=slug, user=user).delete()
context = {'article':article}
return HttpResponse(json.dumps(context), content_type='application/json')
else:
return HttpResponseForbidden()
urls.py
url(r'^delete/(?P<slug>[-\w\d]+)/$', views.article_effacer, name="article_effacer"),
template.html
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
Ajax
$('.delete').click(function(){
var slug = $(this).attr('id');
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
data: {'slug': $(this).attr('id'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response) {
console.log('deleted')
$(".article" + slug).remove();
},
error: function(rs, e) {
console.log(slug)
}
})
})
The problems comes probably from the url, but I don't understand how to correct it, any suggestions?
_ Update _
Full template
{% block content %}
{% for a in article %}
<div class="article{{a.slug}}">
[... unrelated html ...]
{% if a.user == user %} |
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
{% endif %}
</div>
{% endfor %}
{% endblock %}
{% block javascript %}
<script>
$('.delete').click(function(){
var slug = $(this).attr('id');
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
data: {'slug': $(this).attr('id'), 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: "json",
success: function(response) {
console.log('deleted')
$(".article" + slug).remove();
},
error: function(rs, e) {
console.log(slug)
}
})
})
</script>
{% endblock %}
You can't use template tags like that, with values coming from JS; it should be clear that template tags are resolved on the server side, whereas the JS is executed on the client according to what the user clicks.
However you are halfway there by putting the value in the input. Actually, inputs don't have a href attribute, but you could use a data- prefix; the point is that you can then grab that in your JS to use as the URL. Something like:
<input class="delete" id="{{ a.slug }}" data-url='{% url "article.views.article_effacer" a.slug %}' value="Effacer">
var url = $(this).data('url');
$.ajax({
type: "POST",
url: url,
...
});