I'm trying to add an upvote button using ajax + django. Following this example, I was able to set up the following, but nothing happens when I click "upvote". (runserver is not getting any requests)
views.py
#login_required
def upvote(request):
recommendation = None
if request.method == 'GET':
recommendation = request.GET['recommendation']
if recommendation:
recommendation.votes.up(user)
return HttpResponse(upvotes)
urls.py
url(r'^upvote/$', coreviews.upvote, name='upvote'),
html
<p><strong id="like_count">Vote Count: {{ recommendation.get_total_votes }}</strong> people like this category
{% if user.is_authenticated %}
<button id="upvotes" data-recommendation="{{ recommendation }}" class="btn btn-primary" type="button">
<span class="glyphicon glyphicon-thumbs-up"></span>
Like
</button>
{% endif %}
</p>
ajax.js
$('#upvotes').click(function(){
var recommendation;
recommendation = $(this).attr("data-recommendation");
$.get('/upvote/', {recommendation: recommendation}, function(data){
$('#like_count').html(data);
$('#upvote').hide();
});
});
This is essentially what I'm trying to make the button do (works in python shell):
>>> import core.models as coremodels
>>> var1 = coremodels.Recommendation.objects.get(title="test5")
>>> var1.get_total_votes()
0
>>> var1.votes.up(user)
Related
I have a page where I load 2 files. After a click to the load button, this page reload to display a major part of the data, allowing the user to modified it. After a click to lunch button, I want to launch the process and I want to send to another page the path of results files to allow the user to download it.
My problem is after clicking on lunch button and send data to the other page. I have 2 versions :
The first one, send data to the result page, but I do not find a way to take back in the view the data modified by the user, the ajax seems to be ignored because of the type "summit" for the button launch :
<body>
<section class="bg-light py-5 border-bottom">
<div class="container px-5 my-5 px-5">
<div>
<h1 class="display-5 fw-bolder mb-2"> Convert to Dose </h1>
<br>
</div>
<form id="formCTD" action="{% url 'json:convertToDose' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
##here some fields to modified one of them following
<div class="row gx-5 justify-content-center">
<div class="col-lg-4 col-xl-4">
{% if factors %}
<input name="img_path" readonly
class="form-control" {{ pathAnalyseForm.img_path }}>
{% else %}
<input id="btn-submit-form-jsonfile"
class="btn btn-lg" {{ formImgFile.imgFile }}>
{% endif %}
</div>
</div>
<div class="text-center">
<div class="d-grid">
{% if factors %}
<button class="btn btn-primary btn-lg" id="launchButton" type="submit">
Launch
</button>
{% else %}
<button class="btn btn-primary btn-lg" id="submitButton" type="submit">
Load
</button>
{% endif %}
/div>
</div>
</form>
</div>
</section>
</body>
And the js block :
<script type="text/javascript">
$(document).ready(function () {
$("#launchButton").on('submit', function(e) {
e.preventDefault();
var form = $("#formCTD").get(0) //recup en html
// Est-ce que le formulaire est valide ?
console.log("valid? ")
if (form.checkValidity()) {
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ")
nam = $("input[name='img_path']").val()
json = $("input[name='json_path']").val()
console.log(nam)
data = {"img_path" : nam,
"json_path": json}
console.log("bef ajax")
$.ajax({
url: "/filmchromique/convertToDose/",
type: "POST",
data: data,
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", $('input[name="csrfmiddlewaretoken"]').val());
},
success: function (response) {
console.log("ok")
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
})
console.log("after ajax")
}
});
});
</script>
And the view :
def launchCtd(request):
if request.method == 'POST':
#2 after click load
if bool(request.FILES.get('calibrationFile', False)) == True and bool(request.FILES.get('imgFile', False)) == True :
#do some test ok
context = {
'factors': True,
'factorsCalib': factorsCalib,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile': formImgFile,
'pathAnalyseForm': pathAnalyseForm,
'doseRect': doseRect,
'ctrlRect': ctrlRect,
}
return render(request, 'convertToDose.html', context)
after click lunch
else:
if request.is_ajax:
print ("here")#check
img_path = request.POST.get("img_path")
doseRectStr = request.POST.getlist('form[]')
json_pactrlRectth = request.POST.get("json_path")
method = request.POST.get("analyse_type")
if method == 'rb':
#init var
if method == 'multi':
#init var
img_out_path, json_pactrlRectth = functionTOLaunch()
context = {
'filename': img_out_path,
'protocol_file': json_pactrlRectth,
}
return render(request, 'result.html', context)
#1 load init
else:
formCtd = CtdForm()
formJsonFile = JsonFileForm()
formImgFile = ImgFileForm()
context = {
'factors': False,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile' : formImgFile,
}
return render(request, 'convertToDose.html', context)
and the result page is a basic TemplateView.
In this first case, console.log in the ajax are not printed, I do not understand why and I supposed the function is not called (and so the ajax part)
in the second version, views are identical but I modified this on the html :
<button class="btn btn-primary btn-lg" id="launchButton" type="button">
Launch</button>
and this in the js part :
$("#launchButton").on('click', function(e) {....}
Data are sended to the view, I can read it but when I do the render to display the result page with out process data, nothing append... I supposed I have to implement something in the succes ajax part, but I do not understand what I have to do. I supposed I have to implement a new ajax request, to send the new context to the result page but how I take back the context sended by the render in the success ajax ... I'am totaly new and lost on this tech
Thanks for reading :)
what i am trying to do is create a like button just like Instagram's heart. The page must not reload when the like button is clicked, it must simply fill in with the specified color. This is how i am rendering the button in my page:
<a href="#" onclick=
"favPost('{% url 'events:post_unfavorite' post.id %}', {{ post.id }} );return false;"
{% if post.id not in favorites %} style="display: none;" {% endif %}
id="favorite_star_{{post.id}}">
<span class="fa-stack" style="vertical-align: middle;">
<i class="fa fa-star fa-stack-1x" style="color: yello;"></i>
<i class="fa fa-star-o fa-stack-1x"></i>
</span>
</a>
<!-- the second href -->
<a href="#" onclick=
"favPost('{% url 'events:post_favorite' post.id %}', {{ post.id }} );return false;"
{% if post.id in favorites %} style="display: none;" {% endif %}
id="unfavorite_star_{{post.id}}">
<span class="fa-stack" style="vertical-align: middle;">
<i class="fa fa-star fa-stack-1x" style="display: none; color: yello;"></i>
<i class="fa fa-star-o fa-stack-1x"></i>
</span>
</a>
here, events is the name of my django app, "post" is the relevant post on which i need to add the like and "favorites" is a list of favorite posts associated with any posts.
Though i have double checked and i am almost certain that there are no issues with my python code. But i'll still provide the functions for reference.
These are the two views i have created for adding and deleting a favorite:
#login_required
#csrf_exempt
def AddFavoriteView(request, pk):
if request.method == "POST":
print("Add PK",pk)
t = get_object_or_404(Post, id=pk)
t.num_likes = t.num_likes + 1
fav = Fav(user=request.user, post=t)
try:
fav.save() # In case of duplicate key
except Post.DoesNotExist:
pass
return HttpResponse()
#login_required
#csrf_exempt
def DeleteFavoriteView(request, pk):
if request.method == "POST":
print("Delete PK",pk)
t = get_object_or_404(Post, id=pk)
t.num_likes = t.num_likes - 1
try:
fav = Fav.objects.get(user=request.user, post=t).delete()
except Post.DoesNotExist:
pass
return HttpResponse()
The problem is, nothing happens when i click the rendered star, and i get this error in my browser console:
Uncaught ReferenceError: favPost is not defined
Can someone please help me with this?
Thank You
I am trying to implement a like button to my blog post using Ajax, I am facing an error which I am unable to fix so I started from scratch more than once with the following steps:
Created Post model and Like model
Added the views which is currently working perfectly fine when I click like and unlike
I took the like section from the post_detail.html and added it in a separate html like_section.html
added the ajax with the correct values
Now my problem is that when I press the like button a new page is opened with ajax output
{"form": "....(html and ajax codes repeated)......"}
My question is how do I fix this error so that I can submit a like without refreshing the page?
Here are the models for Posts.py
class Post(models.Model):
---------other attributed like: title, content, author, date_posted, slug-----
likes = models.IntegerField(default=0)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
Here are the views:
def like_post(request):
user = request.user
if request.method == 'POST':
post = request.POST.get('post_id')
post_obj = Post.objects.get(id=post)
current_likes = post_obj.likes
if user in post_obj.liked.all():
post_obj.liked.remove(user)
current_likes = current_likes - 1
else:
post_obj.liked.add(user)
current_likes = current_likes + 1
post_obj.likes=current_likes
post_obj.save()
like, created = Like.objects.get_or_create(user=user, post_id=post)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
context = {
'post': post,
}
if request.is_ajax:
html = render_to_string('blog/like_section.html',context, request=request)
return JsonResponse({'form': html})
Here is the post details.html
<!-- Like -->
<div id="like-section">
{% include 'blog/like_section.html' %}
</div>
<!-- Like -->
Here are the like-section.html
<form action="{% url 'blog:like-post' %}" method="POST" class="like-form" id="{{post.id}}">
{% csrf_token %}
<input type="hidden" name="post_id" value='{{post.id}}'>
{% if user not in post.liked.all %}
<button id="like" value='{{post.id}}' class="bwhite sm-button" style="color: grey; background-color: Transparent; background-repeat:no-repeat; border: none; cursor:pointer; overflow: hidden; outline:none;">
<i class="far fa-thumbs-up" type="submit"></i>
</button>
{% else %}
<button id="like" value='{{post.id}}' class="bwhite sm-button" >
<i class="far fa-thumbs-up" type="submit"></i>
</button>
{% endif %}
<div class="like-count{{post.id}}">{{ post.num_likes }} Likes</div>
</form>
Here is the ajax:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript"></script>
<script>
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault();
var pk = $(this).attr('value');
$.ajax({
type: 'POST',
url: '{% url "blog:like-post" %}',
data: {'post_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>
Here is the urls.py
path('blogs/like', like_post, name='like-post'),
You are returning an HTML page as response from your view, I think that might be causing it. First just try returning something like {"msg","worked"} and see if its works
Need achieve some features like [http://webonise.co.uk/][1] when click on contact,resume,resources link will update (location URL&div content) but without refresh the page.
Flask view function
#app.route('/')
def index():
flash('Welcome')
return render_template('index.html')
Under index.html is extends base.html
{% block content %}
{{super()}}
<section class="content">
<i class="mdi-event"></i>Event
<i class="mdi-contact"></i>Contact
<div class="board">
{# dynamic template #}
{# without using {{% include 'event.html' %}} #}
</div>
</section>
{%- endblock %}
How can i dynamic rendar event.html / contact.html content when different link is click and rendar under {# dynamic template #} without refresh the page ?
<!--event.html-->
<ul class="list">
<li>
<h3>123</h3>
<p>abc</p>
</li>
</ul>
What I try
import jinja2 Environment but still no idea how to achieve this
env = Environment(autoescape=True,
loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
#app.route('/')
def index():
board = env.get_template('event.html')
flash('Welcome Home Tyler')
return render_template('index.html', board=board)
Is there really need ajax technique get/post method to achieve all this?
You can use Flask-Sijax which helps you add Sijax support to your Flask app. Sijax is a python/jquery library that makes AJAX easy to use on your web applications. Alternatively you could do this:
<script>
$(document).ready( function() {
$('#next').click(function() {
$.ajax("{{ url_for('yourroute') }}").done(function (reply) {
$('#container').html(reply);
});
});
});
</script>
<input type="button" id="next" value="Next" />
<div id="container"></div>
Hi I create my first project like stackoverflow(question-answer). I used this guid from Tango with Django http://www.tangowithdjango.com/book17/chapters/ajax.html to add like button with ajax. And nothing hapened. Don't see any request in console. I'm noob in Django, and it's my first encounter with jquery.
apps/questions/models:
class Answer(models.Model):
text = models.TextField()
date = models.DateTimeField(default=datetime.datetime.now)
likes = models.IntegerField(default=0)
resolve = models.IntegerField(default=0)
author = models.ForeignKey(CustomUser)
question = models.ForeignKey(Question)
apps/questions/views:
#login_required
def add_like(request):
ans_id = None
if request.method == 'GET':
ans_id = request.GET['answer_pk']
likes = 0
if ans_id:
ans = Answer.objects.get(id=(int(ans_id)))
if ans:
likes = ans.likes + 1
ans.likes = likes
ans.save()
return HttpResponse(likes)
apps/questions/ulrs:
url:
url(r'add_like/$', views.add_like, name='add_like'),
question.html:
{% for answer in answers %}
<div class="container-fluid no-padding">
{{ answer.text }}
</div>
<div class="container-fluid author-question">
<p>posted: {{ answer.date.day|stringformat:"02d" }}.{{ answer.date.month|stringformat:"02d"}}.{{ answer.date.year}}</p>
<p>by: {{ answer.author.username }}</p>
</div>
{% if user.is_authenticated %}
<button class="btn btn-default" type="button" id="likes" data-ansid="{{ answer.id }}">
like | <strong id="like_count">{{ answer.likes }}</strong>
</button>
{% endif %}
js/ajax.js:
$('#likes').click(function(){
var ansid;
ansid = $(this).attr("data-ansid");
$.get('/questions/add_like/', {answer_id: ansid}, function(data){
$('#like_count').html(data);
$('#likes').hide();
});
});
Since you are creating buttons in a for loop, and naming them the same way, you have multiple elements on the page with the same id. Because of this you get unpredictable results. You should either give each button its own id, or change the jQuery selector to select the buttons based on the appropriate class.
For example, you could have:
{% for answer in answers %}
<div class="container-fluid no-padding">
{{ answer.text }}
</div>
<div class="container-fluid author-question">
<p>posted: {{ answer.date.day|stringformat:"02d" }}.{{ answer.date.month|stringformat:"02d"}}.{{ answer.date.year}}</p>
<p>by: {{ answer.author.username }}</p>
</div>
{% if user.is_authenticated %}
<button class="btn btn-default likes-button" type="button" data-ansid="{{ answer.id }}">
like | <strong id="like_count">{{ answer.likes }}</strong>
</button>
{% endif %}
{% endfor %}
And then for the javascript
$('.likes-button').click(function(){
var ansid;
ansid = $(this).attr("data-ansid");
$.get('/questions/add_like/', {answer_id: ansid}, function(data){
$('#like_count').html(data);
$('#likes').hide();
});
});