Django: return Httpresponse before sending email - python

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.'})

Related

django; How to create view (function) without template

Is it possible to create function without template?
Like I'm trying to create delete function and what I want to do is to delete something immediately after clicking the delete button and then redirect to other page.
I want to place a delete button on the page users can edit their post.
html is like this
<button type="submit" class="btn btn-outline-secondary">Save Changes</button>
</form>
and I want to place delete button next to this button.
def edit_entry(request, entry_id):
'''Edit a post.'''
entry = Entry.objects.get(id=entry_id)
if request.method != 'POST':
form = EditEntryForm(instance=entry)
else:
form = EditEntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse_lazy('main:index'))
return render(request, 'main/edit_entry.html', {'entry': entry, 'form': form})
def delete_entry(request, entry_id):
'''Delete post'''
#I don't wanna create template for this function.
pass
Anyone who can give me tips?
by the docs simple-view you can use the httpresponse
from django.http import HttpResponse
def delete_entry(request, entry_id):
'''Delete post'''
#I don't wanna create template for this function.
return HttpResponse('done')
Usually it make sense to use ajax for this purpose.
In this case the handling of click splits into steps:
1) You click the button
2) jQuery (or any other javascript code) catches click event and sends AJAX request (usually post request, because post is used to for data modifications in REST agreement) to defined url on your server (like /delete/my/some/thing/) in urls.py
3) Djnago routes request to the delete_something view (or function)
4) delete_something takes request, checks what you want to check (like some permissions of current user), deletes what you actually want to delete and makes ajax response.
5) jQuery takes this response (which it actually waits on 3-4 steps) and checks response content to detect if server says everything is ok or there is some error.
So this is the code to create ajax request from jQuery:
$('#delete-button').click(function(){
var delete_id = (#delete-button).data()
$.ajax
({
url: '/delete/my/some/thing/',
data: {"id": delete_id},
type: 'post',
success: function(result)
{
// here you can write code to show some success messages
},
error: function(result) {
// here you can write code to show some error messages or re-send request
}
});
});
You also can use not $.ajax() method, but $.post(), if you want.
This is the code from this answer to make Django json response:
return HttpResponse(json.dumps(response_data), content_type="application/json")
It could look like this:
import json
from django.http import HttpResponse
def delete_something(request):
resp_data = {}
user = request.user
delete_id = request.POST.get('delete_id') # or None, if there is no delete_id
# here you can check user permissions, if your site has them
# for example check that user can delete something and can delete this entity by writing check_user_can_delete() function
if delete_id and check_user_can_delete(user):
# do your deletion
resp_data = {'status': 'ok'}
else:
resp_data.update(errors=[])
if no delete_id:
resp_data['errors'] = 'no delete_id'
if not check_user_can_delete(user):
resp_data['errors'] = 'you cave no permissions to delete delete_id'
resp = json.dumps(resp_data)
return HttpResponse(resp, content_type='application/json')
Also note that Django 1.7 has JsonResponse object, as shown in SO answer I mentioned.

Django view not rendering after Ajax redirect

The main page of my website has multiple buttons at the top. Whenever one of these buttons is pushed, a get request is sent to a django view, which is redirected and a queryset of django models is filtered and eventually displayed on the web page. I know that my ajax works because the terminal says the request is redirected properly. The function it redirects to also seems to be working, as it is quite simple and has not thrown any errors. However, my view remains the same and I'm not sure why.
urls.py
url(r'ajax_filter/', views.ajax_filter, name='ajax_filter'),
url(r'filter=(\w+)/$', views.filtered_index, name='filtered_index'),
views.py
def filtered_index(request, filter):
clothes = Clothes_Item.objects.filter(gender=filter)
if request.user.is_authenticated():
favorite_clothes_ids = get_favorite_clothes_ids(request)
return render(request, 'test.html', {'clothes': clothes, 'favorite_clothes_ids': favorite_clothes_ids})
else:
return render(request, 'test.html', {'clothes': clothes, })
def ajax_filter(request):
if request.is_ajax():
gender_filter = request.GET.get('gender_filter') #filter type
if gender_filter is not None:
return HttpResponseRedirect(reverse('filtered_index', args=[gender_filter]))
return HttpResponse('')
You can not use Django redirect in your case. When you send an ajax request you usually expect a json response, and based on that you can redirect the user via your JavaScript code.
$.ajax({
// You send your request here
}).done(function(data) {
// You can handle your redirection here
});
Here is how you can handle a redirect with your setup, you pass back a JsonResponse from django with the next page that you want to go to:
from django.http import JsonResponse
def ajax_filter(request):
if request.is_ajax():
gender_filter = request.GET.get('gender_filter') #filter type
if gender_filter is not None:
return JsonResponse({
'success': True,
'url': reverse('filtered_index', args=[gender_filter]),
})
return JsonResponse({ 'success': False })
In JS, you use done (or success) function to grab the URL from the passed back JsonResponse and redirect to that URL using window.location.href:
$.ajax({
// You send your request here
}).done(function (data) {
if (data.success) {
window.location.href = data.url;
}
});

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 Email sent twice

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.

how we can use ajax() in views.py in django? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have little code over here.
Can you please explain me that what that code exactly does in details. please.
In script here is the ajax call:
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
How ajax is works in django and how can we use ajax request in view.
Here my views
views.py
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
Thanks in Advance.
In general, $.ajax method sends an asynchronous http request.
You can read about it here.
First argument is url, where we send request.
Second, is request method it may be GET, POST, PUT, DELETE and etc. see wiki
Third argument is key-value dictionary with data, which you use in server-side.
In django, you may access it in request.POST(in case of post request)
Fourth argument is function, which is invoked when server succesfully returns response.
You do not need if statement in this function, because when request fails or server does not give a response, or server returns error(something like 40* code for example) this function will not be invoked.
This function takes one argument with server's response. You need handling this data, for example showing user a message like Invalid data, please correct errors... or Valid data. your request is in process now. and staff like that.
Last argument is data type of servers response. jQuery is smart enough to parse json or html for you, so in this case, response(argument of success function) is pure JS object, deserialized from JSON.
In your server-side(Django views) you must do some validation of request's data. and do something with it. For example, save it to database. When i have to implement ajax form processing i do sumething like this:
if request.method == 'POST':
response = {}
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
response['success'] = 1
else:
response['success'] = 0
response['errors'] = dict(form.errors)
return HttpResponse(simplejson.dumps(response), mimetype = 'application/json' )
And on client side, in js something like this
$.post('/url/to/view',
function(json){
if(json['success']){
alert('Yahooo! Successfull request')
}
else{
alert('Oooops. Looks like you send invalid data')
}
}, 'json')
Good luck!

Categories