I'm trying to post a very simple comment with Ajax, when I'm not using Ajax the comment is posted and saved to the database just fine.
So far I've encountered 501 and 403 errors and all sorts of unwanted behaviour. I've tried to follow these instructions and I've read several answers on a similar topic on stackoverflow, but was unable to apply those solutions to my problem.
I'm really stuck here so any help would be greatly appreciated.
Relevant models.py:
class Photo(models.Model):
image = models.ImageField(
'image path', upload_to='images/%Y/%m/%d')
image_thumb = models.ImageField(
'thumbnail path', upload_to='images/thumbnails/%Y/%m/%d')
name = models.CharField(max_length=100)
description = models.CharField(max_length=150)
avg_rating = models.FloatField('average rating', default=5.1)
def __unicode__(self):
return self.description
class Comment(models.Model):
post_date = models.DateTimeField('posted')
comment_text = models.TextField(max_length=500)
photo = models.ForeignKey(Photo)
def __unicode__(self):
return self.comment_text
The comment form from forms.py:
class CommentForm(forms.Form):
comment_text = forms.CharField(widget=forms.Textarea)
And the view which normally handles comments in views.py:
def details(request, photo_id):
photo = get_object_or_404(Photo, pk=photo_id)
ratings_list = photo.rating_set.all().order_by('-id')
if request.method == 'POST':
form_c = CommentForm(request.POST)
if form_c.is_valid():
new_comment = Comment(
post_date = datetime.now(),
comment_text = form_c.cleaned_data['comment_text'],
photo = photo
)
new_comment.save()
if request.is_ajax():
return "???"
else:
return HttpResponseRedirect(reverse('photos:details', args= (photo_id,)))
else:
form_c = CommentForm()
return render(request, 'photos/details.html',
{'photo': photo, 'ratings_list': ratings_list[:5],
'form_c': form_c})
I've put question marks in there since by now I have no idea where should I redirect.
Relevant details.html template snippet:
<div id="commentSection">
{% for c in photo.comment_set.all %}
<p>On {{c.post_date|date:"dS \o\f F, \a\t H:i"}}, someone said: </p>
<p>{{c.comment_text}}</p>
<br>
{% endfor %}
</div>
<form id="commentForm" name="commentForm" action="{% url 'photos:details' photo.id %}" method="post">
{% csrf_token %}
<p>{{form_c.non_field_errors}}
{{form_c.comment_text.label_tag}}
{{form_c.comment_text.errors}}</p>
<p>{{form_c.comment_text}}</p>
<input type="submit" value="Post Comment" />
</form>
The urls.py:
from django.conf.urls import patterns, url
from photos import views
urlpatterns = patterns('',
url(r'^rate/(?P<photo_id>\d+)/$', views.rate, name='rate'),
url(r'^(?P<photo_id>\d+)/$', views.details, name='details'),
url(r'^$', views.index, name='index'),
)
I've added this script to avoid having the csrf validation fail when trying to submit comments via Ajax.
<script type="text/javascript">
$(document).ajaxSend(function(event, xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function sameOrigin(url) {
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
And this is the Ajax part I've been struggling with today and yesterday:
$(document).ready(function() {
$('#commentForm').on('submit', function(e){
e.preventDefault();
var form = $(this);
$.ajax(
???
});
});
});
Thank you for your time.