Django Email sent twice - python

I have an odd problem.....I was fiddling with django's email backend...tested both console and smtp backend.....the email is sent twice! I can't trace why its happenning....
here's the view that calls the email sending operation:
from django.http import HttpResponse
from django.core.mail import send_mail, EmailMessage
def index(request):
if request.method in ('GET'):
print request.method
mail = EmailMessage(subject='Subject Here', body='Here be the msg!', from_email='admin#test.com', to=['recipient#email.com'])
mail.send()
#send_mail(subject='Subject Here', message='Here be the msg!', from_email='admin#test.com', recipient_list=['recipient#email.com'])
return HttpResponse('Mail Sent')
As can be seen, I used both EmailMessage class with send() method and also the send_mail() function.....but both behaves the same.....and the email is sent twice!!
Any help?

I have the same problem, and spent hours looking for a solution, which I think I found with help from this link. I think my web browser may be the root cause of this problem.
I have an ajax call to the Django view followed by a window.redirect
request = $.ajax({
url: "{% url 'add_to_cart' %}",
type: "post",
data: {
ajax: 'yes',
ids: JSON.stringify(IDs),
xxxx: $("#xxxx").val(),
csrfmiddlewaretoken: getCookie('csrftoken')
}
}).done(function (response) {
if (response == "OK") {
$('#cart_name').val('');
window.location.href = '/';
}
});
I just delete window.location.href = '/';
This prevent the brower to send twice the ajax call. I don't have much time to investigate why a simple window.location.href = '/'; make a second unwanted call.

Related

How to return relative to request django

In my django project, I built a little like-button. The problem is, that I had it only when I take a detailed view on a post, and now want to put it on the home page, where multiple posts are shown. The problem the Like Function of the button returns to the detailed page, but I want to make the return dependent from the url where the like came from, so that I can just scroll ahead on the home page or what ever page am on, without being returned to another page. So here is my views.py Like function:
def PostLike(request, pk):
post = get_object_or_404(Post, id=request.POST.get('post_id'))
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return HttpResponseRedirect(reverse('post-detail', args=[str(pk)]))
So in a nutshell: how could I change my Like function so that I am returned to the page I liked from?
Your function returns a Redirect, that's why you are redirected to the detail page.
If you want to stay on the same page after clicking 'Like' you could submit a request through Ajax and return a JsonResponse with a message or a value depending on what you get from the database query.
How to do this varies based on what JS library or framework you are using. Here is a simplistic JQuery example:
in views.py
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
def like_or_unlike(request, id):
if request.user.is_authenticated:
try:
post = get_object_or_404(Post, id=id)
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
message = 'You unliked post ' + id
else:
post.likes.add(request.user)
message = 'You liked post ' + id
except:
message = 'Error processing like for post ' + id
else:
message = 'You must be logged in to like a post.'
return JsonResponse({ 'result': message })
in urls.py
from django.urls import path
from . import views
urlpatterns = [
...
path("like/<id>/", views.like_or_unlike),
]
in template.html
<button class="{% if post.liked %}color-blue{% else %}color-white{% endif %}"
id="post_{{ post.id|stringformat:"s" }}"
onclick="postLike( '{{ post.id|stringformat:"s" }}' )"> Like this post </button>
<script>
function postLike(id) {
var element = "#post_" + id
$.ajax({
url: '/like/' + id,
type: 'get',
contentType: 'application/json',
success: function(data) {
console.log(data);
if $(element).hasClass("color-white") {
$(element).removeClass("color-white");
$(element).addClass("color-blue");
} else {
$(element).removeClass("color-blue");
$(element).addClass("color-white");
}
},
error: function(jqXhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
</script>
I think you should use Ajax request for it so you don't even reload page. Just handle it in JavaScript.
Otherwise you can redirect base on request.referer value to go back to the view where click was made

Django: return Httpresponse before sending email

I'm trying to make a contact form with python django, at this time it works perfectly, the issue is that I have to wait up to the email message already sends to get the Httpresponse.
Is there any way to return the Httpresponse first and then send the email message?
send_mail(
'Subject here',
data['comentarios'],
'myemail#gmail.com',
['myemail#gmail.com'],
fail_silently=False,
)
return HttpResponse('bien') #es menor a 7 digitos
I assume you want to let the user see that the email has been sent/the request has been processed immediately after clicking 'Send'. I suggest that you use AJAX to achieve what you are doing.
Thought Process
One thing to note is that you probably want to show a loading gif/svg or something to indicate that the email is in the process of being sent. While the loading gif is shown, proceed with form validation:
if everything is ok: proceed with AJAX request send email and return a success/error message indicating whether email was sent.
if validation failed: just display error messages
However, if you want to display a message, like 'Thank you', it's something like this:
It should probably look something like this in your JS (if you're using jQuery):
$('#form').on('submit', function(e) {
e.preventDefault();
// do some validation
// if the validation deems the form to be OK - display the 'Thank you!` message first THEN proceed to AJAX request.
$('#form').append('Thank you!');
// insert AJAX here
...
// if the validation returns errors - just display errors
...
});
The actual AJAX request:
// AJAX request
$.ajax({
method: 'POST',
url: '../send_email/', # Just an example - this should be a url that handles a POST request and sends an email as a response
data: $('#form').serialize(),
success: function(response) {
// anything you want
// an example would be:
if (response.success) {
$('#form').append(response.success);
}
});
In your views.py:
class SendEmail(View):
def post(self, request, *args, **kwargs):
if request.is_ajax():
send_mail(
'Subject here',
data['comentarios'],
'myemail#gmail.com',
['myemail#gmail.com'],
fail_silently=False,
)
return JsonResponse({'success': 'Just a JSON response to show things went ok.'})
return JsonResponse({'error': 'Oops, invalid request.'})

Django: call python function when clicking on button

Let's say that I have a python function that only sends email to myself, that I want to call whenever the user clicks on a button in a template, without any redirection (maybe just a popup messege).
Is there a way to do that?
To send an email without reloading the page you might want to send a request with ajax. Here are some details.
For example, you could write the following ajax function:
$('#button').on('click', function() {
$.ajax({
url: '/send_mail/',
data: {email: 'send'},
type: 'GET',
}).done(function() {
alert('Well done!')
});
});
And in a view you can handle it almost as a simple request:
from django.http import Http404
...
if request.is_ajax():
if request.GET.get('email') == 'send':
# send email
else:
raise Http404
In your views you can handle any incoming get/post requests. And based on handler for that button (and this button obviously must send something to server) you can call any function.

django POST returning Internal Server 500 error

I am trying to POST a request to a django view but it keeps returning INTERNAL SERVER ERROR 500.
My ajax post:
$.ajax({
url : "/loginAction/",
type : "POST",
async : false,
data : {action:'loginAction',
email:email,
password:password},
success : function(response) {
$.niftyNoty({
type:"success",icon:"",title:"Login Successful. Redirecting....",container:"floating",timer:5000
});
},
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText);
$.niftyNoty({
type:"danger",icon:"",title:"Wrong Email OR Password",container:"floating",timer:5000
});
}
});
My django view:
def loginAction(request):
print "Its workjing"
if request.method == 'POST' and 'loginButton' in request.POST:
email = request.POST.get('email')
password = request.POST.get('password')
print email, password
return HttpResponse(json.dumps({}),content_type="application/json")
My urls.py
urlpatterns = [
url(r'^', views.loginPage, name='loginPage'),
url(r'^loginAction/', views.loginAction, name='loginAction')
]
The ajax POST is not hitting the django view. It is not printing Its working in console. So its not returning the json response to ajax call. I also tried normal form POST but same result. I am using django 1.9.2. I cant figure out why this error?
It returns this error code:
Internal Server Error: /loginAction/
Traceback (most recent call last):
File "/home/manish/Desktop/admin_picknbox/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 158, in get_response
% (callback.__module__, view_name))
ValueError: The view login_app.views.loginPage didn't return an HttpResponse object. It returned None instead.
EDIT:
ajax Header:
jQuery(document).ready(function($){
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
});
It seems your urls are the problem because in the error appears that the loginPage view is called although you go to /loginAction/. So try to add $ at the end of each regex as below:
urlpatterns = [
url(r'^$', views.loginPage, name='loginPage'),
url(r'^loginAction/$', views.loginAction, name='loginAction')
]
Because it appears that your first regex r'^' captures any url.
Your view function doesn't take care of all cases, in case if request.method == 'POST' and 'loginButton' in request.POST: is False, you view function doesn't return anything, hence the error. Python function, if left without explicit return statement, would return None.
Edit:
If your print statement is not even executed, then you must have 403 response from django. You need to pass csrf token when you make ajax call to prevent attack from unknown person. Django would check csrf automatically, but you need to pass it as part of the data:
data : {action:'loginAction',
email:email,
password:password,
csrfmiddlewaretoken: '{{ csrf_token }}'},
Also, you should check "action" in request.POST not "loginAction" in request.POST.
i got this error one day but i latter realize that the page returning internal server error has the same name as the html page i wanted to return. i just changed the name of the html page i wanted t return and everything worked fine

What is a best practice to receive JSON input in Django views?

I am trying to receive JSON in Django's view as a REST service. I know there are pretty developed libraries for REST (such as Django REST Framework). But I need to use Python/Django's default libraries.
request.POST is pre processed by django, so what you want is request.body. Use a JSON parser to parse it.
import json
def do_stuff(request):
if request.method == 'POST':
json_data = json.loads(request.body)
# do your thing
Send the response to browser using HttpResponse without page refreshing.
views.py
from django.shortcuts import render, HttpResponse,
import simplejson as json
def json_rest(request):
if request.method == "POST":
return HttpResponse(json.dumps({'success':True, 'error': 'You need to login First'}))
else:
return render(request,'index.html')
urls.py
(r^'/','app.views.json_rest')
client side:
$.ajax({
type:"post",
url: "/",
dataType: 'json',
success: function(result) {
console.log(result)
}
});

Categories