Django: How to Like an Object with Ajax - python

Here's my View,
class ObjLike(RedirectView):
def get_redirect_url(self, *args, **kwargs):
id = self.kwargs.get('id')
obj = get_object_or_404(Data, id=id)
user = self.request.user
if user.is_authenticated():
if user in obj.likes.all():
obj.likes.remove(user)
else:
obj.likes.add(user)
So after this view how can I redirect user to the same page?
I used "return redirect(request.META['HTTP_REFERER'])" but it gives an error "name 'request' is not defined"
I can't use the get absolute URL method, i'm using this view at several places.
So, how can I do that?

to like an object with ajax calls do this
first in html we want to make a like button:
<button id="like">Like!</button>
the add a script that contain the ajax:
<script>
$(document).ready(function() {
$("#like").click(function(event){
$.ajax({
type:"POST",
url:"{% url 'like' Obj.id %}",
success: function(data){
confirm("liked")
}
});
return false;
});
});
</script>
the we add the like url to the urlpatterns list:
url(r'like/obj/(?P<pk>[0-9]+)/', views.like, name="like"),
adding the view :
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def like(request, pk)
obj = Obj.objects.get(id=pk)
obj.likes += 1
obj.save()
return HttpResponse("liked")
Note: you can customize the like view to check if user liked already

Related

Django - "return render(...)" doesn't work in a view that interacts with an ajax request

I want to solve this task: I click a button on the first page and after that my view creates a chat room and redirects me to the chat page.
I decided to use ajax request for this task, but I have a problem, my view works until line return render(request, 'chat/chatroom.html'), the chat room is created, but the chat/chatroom.html page doesn't open, I don't understand why. I have no errors, the return render(request, 'chat/chatroom.html') line does nothing.
My code:
html
<button type="submit" id="chat-button" value="{{advertisement.author.id}}">Write to the author</button>
<script>
$(document).on('click', '#chat-button', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "main_app:create-chat" %}',
data: {
send_to_id: $('#chat-button').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
},
error: function (xhr, errmsg, err) {
}
});
})
</script>
views.py
from django.contrib.auth import get_user_model
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from chat.models import Thread
User = get_user_model()
#method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
def post(self, request):
send_to_id = int(request.POST.get('send_to_id'))
send_to = User.objects.get(id=send_to_id)
auth_user = request.user
final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) \
| Q(Q(first_person=auth_user) & Q(second_person=send_to))
thread = Thread.objects.filter(final_q)
if not thread:
Thread.objects.create(first_person=auth_user, second_person=send_to)
return render(request, 'chat/chatroom.html')
urls.py
app_name = 'main_app'
urlpatterns = [
...
path('create_chat', CreateChat.as_view(), name='create-chat')
]
I guess ajax request is not the best solution, but I don't know how to implement this feature in another way.
Thanks for the help.
AJAX always returns to request when it is called, so you can't render it to a new view. so to do this, when the request has been successfully completed, return status 200, etc. when getting the success response in AJAX call. likely in
success: function (json) {
},
redirect it to the desired view. so the code will be like that.
from http.client import OK
from django.http import JsonResponse
#method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
def get(self,request):
return render(request, 'chat/chatroom.html')
def post(self, request):
send_to_id = int(request.POST.get('send_to_id'))
send_to = User.objects.get(id=send_to_id)
auth_user = request.user
final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) \
| Q(Q(first_person=auth_user) & Q(second_person=send_to))
thread = Thread.objects.filter(final_q)
if not thread:
Thread.objects.create(first_person=auth_user, second_person=send_to)
return JsonResponse({},status=OK)
and the AJAX request will be like that
<script>
$(document).on('click', '#chat-button', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "main_app:create-chat" %}',
data: {
send_to_id: $('#chat-button').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
location.href = "create-chat" // from here render create-chat
},
error: function (xhr, errmsg, err) {
}
});
})
</script>

Unable to render a template after using fetch in django

I have the following requirement:
Send data to backend using fetch()
receive the data in a view and render another template ( route to a different view)
The following is my code snippet:
JS:
fetch("/addpost", {
method: "POST",
body: JSON.stringify({ value: selecteddict }),
headers: {
"Content-type": "application/json;",
},
})
.then((res) => {
return res.text();
})
.then((text) => {
console.log(text);
});
// the data is being sent successfully
Django View1:
#csrf_exempt
def addpost(request):
if request.method == 'POST':
song = json.loads(request.body.decode('utf-8'))['value']
print(song)
# I want to redirect to another view called createpost that renders a new page
return JsonResponse({'status':201})
return render(request, 'addpost.html')
Django createpost view:
def createpost(request):
return render(request, 'createpost.html')
The view createpost is working fine when given the required path but it is not rendering when it's redirected from addpost
Please suggest a solution to this.
Your addpost view returns as JsonResponse in case of a POST request. If you want to redirect somewhere you need to use redirect() instead of JsonResponse()

I want to get value is selected in ChoiceField

I wrote forms.py like
# -*- coding: utf-8 -*-
from django import forms
class InputForm(forms.Form):
name = forms.CharField(max_length=100)
select1 = forms.ChoiceField(widget=forms.RadioSelect,required=False)
select2 = forms.ChoiceField(widget=forms.RadioSelect,required=False)
in html
<div>
{{ f.select1 }}
<label for="select1" dataGoTo="7">select1</label>
{{ f.select2 }}
<label for="select2">select2</label>
</div>
in views.py
def get_data(request):
if request.method == "POST":
form = InputForm(data=request.POST)
if form.is_valid():
name = form.cleaned_data['name']
I want to get value which select1 or select2 is selected.
How should I write in views.py?
You could accomplish this in Javascript using Ajax. Right click the page in your browser and select 'view source'. Figure out what are your form's and select element's id or class. Then in your Javascript (jQuery) right the following:
"use strict";
$(document).ready(function() {
$('form#form_id').on('submit', function(){
// your option elements must have a 'value' attribute
var selectedValue = $('select#select_id').val();
$.ajax({
type:'POST',
url:'your/view/url',
data:{
'selected': selectedValue,
},
dataType: 'json',
success:function(data){
// error handling
if (data['status']==='ok') {
// display success message
} else {
console.log(data);
}
}, // success
}); //ajax
}); // on form submit
}); // document ready
Then in your views.py:
from django.views.generic import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
class SomeAjaxView(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
if request.user.is_authenticated:
selected = request.POST.get('selected', None)
if selected:
# do something here
return JsonResponse({'status':'ok'})
else:
return JsonResponse({'status':'ko', 'error': 'Value missing'})
return JsonResponse({'status':'ko', 'error': 'Not authenticated'})
Using Ajax has the benefit of not refreshing the entire page on submit. This is the industry-standard practice nowadays.

Django AJAX search function

I'm trying to make a search function in my Django project using AJAX. But the functions in views.py don't seem to work properly. And maybe I have some other mistakes. Could you please tell me what I need to correct?
This is my AJAX file:
$(document).ready( function(){
$('#suggestion').keyup(function(){
var query;
query = $(this).val();
$.get('/friends_plans/suggest_users/', {suggestion: query}, function(data){
$('#user').html(data);
});
});
});
This is part of my template:
<div>
<ul class="nav nav-list">
<li class="nav-header">Find user</li>
<form>
<li><input class="search-query span10" type="text" name="suggestion" value=" " id="suggestion" /></li>
</form>
</ul>
</div>
<div id="user">
</div>
These ara functions from views.py:
def suggest_users(request):
users_list = []
starts_with = ''
if request.method == 'GET':
starts_with = request.GET['suggestion']
users_list = get_users_list(5, starts_with)
return render(request, 'friends_plans/list.html', {'users_list': users_list})
def get_users_list(max_results=0, starts_with=''):
users_list = []
if starts_with:
users_list = Person.objects.filter(username__istartswith=starts_with)
if max_results > 0:
if len(users_list) > 0:
users_list = users_list[:max_results]
return users_list
This is from urls.py:
url(r'^suggest_users/$', views.suggest_users, name='suggest_users')
The istartswith method doesn't work properly with the variable but does with the constant, I can't understand why. And suggest_users function doesn't return users_list to the object with id user ($('#user').html(data)), nothing appears on the page. But maybe there are some other mistakes.
Django's render function renders HTML after parsing it with Jinja. If you want to write a view that acts as an endpoint for an AJAX function, you do not want that view to return render.
Instead you should use return JsonResponse. JsonResponse accepts a dictionary as an argument. And it builds a proper JSON object for you. :) Which will then be picked up by your AJAX's success function.
Here's an example of how to use JsonResponse:
from django.http import JsonResponse
def some_endpoint(request, *args, **kwargs):
data = dict()
data["foo"] = "bar"
data["username"] = User.objects.get(id=request["id"]).username
return JsonResponse(data)
This will cause your view to return a JSON Object, which is what your AJAX function is looking for.
Second suggestion I would make would be to use jQuery's $.ajax() function rather than jQuery's shortcut .get() function. The advantage of this would be learning all the parameters that go along with AJAX calls.
Here's an example of jQuery's $.ajax() function.
$(document).ready( function(){
$('#suggestion').keyup(function(){
var query = $(this).val();
$.ajax(function(){
type: "GET",
url: "/friends_plans/suggest_users/",
data: {suggestion: query},
success: function(data){
console.log("SUCCESS");
console.log(data);
},
failure: function(data){
console.log("FAIL");
console.log(data);
},
});
});
});

Issues with ajax in django

I'm using ajax in django first times .. I read some tutorials on the net and I'm trying to make a simple form which posts some information via ajax.
Here is my html form
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
function send_request()
{
$.ajax({
type:"POST",
url:"/ajaxredirect/",
});
}
</script>
<button type="button" onclick="send_request();">change content</button>
and it is my view
def Ajaxquery(request):
if request.is_ajax():
return HttpResponse("ok")
else:
return HttpResponse("error")
it does nothing when i am click on change content button in browser.
Any suggestions would be apperciated
Here is basic request/response setup I have made use of. I got the JSONResponse and AjaxResponse mixins from the Django Braces Module. I also made sure to include the following Django CSRF fix to prevent my AJAX request from being treated as a cross site request forgery.
JQuery:
<script type="text/javascript">
function send_request() {
$.ajax({
type: 'POST',
url: '/ajaxredirect/',
data: $('#your_form').serialize(),
crossDomain: false,
success: function(ctx) { console.log(ctx); },
});
}
</script>
Views.py
from django.views.generic import View
from braces.views import JSONResponseMixin, AjaxResponseMixin
class AjaxResponseView(JSONResponseMixin, AjaxResponseMixin, View):
def post_ajax(self, request, *args, **kwargs):
data = request.POST.items() # form data
ctx = {'hi': 'hello'}
return self.render_json_response(ctx)

Categories

Resources