2016-10-14 2 views
0

Je crée une application FAQ. Dans ma page de détail d'article j'essaye de mettre en application un système de vote. L'objectif est de permettre à un utilisateur de voter pour un article s'il le juge utile. Je ne souhaite pas que la page soit actualisée lorsque l'utilisateur clique sur le bouton "Voter vers le haut". J'ai choisi d'utiliser un appel Ajax à partir du modèle le long d'une URL vers un UpdateView.Django: Passage d'un jeton csrf par ajax à une méthode UpdateView 405 introuvable erreur

Django a besoin d'un jeton csrf pour être transmis. Le problème que je rencontre est une erreur 405 (Method Not Allowed). J'ai vérifié dans mon paramètre de réseau dans chrome dev que le jeton csrf est généré et assigné dans l'en-tête http. Je pense que la question peut se poser, mais tout ce que j'ai essayé jusqu'ici a échoué. Toute direction serait utile.

EDIT MISE À JOUR:

J'utilise Django 1,10

L'URL:

from django.conf.urls import url 
from faq.views import * 

urlpatterns = [ 
    url(r'^ironfaq/$', DashboardView.as_view()), 
    url(r'^ironfaq/(?P<slug>[\w-]+)/$', SectionView.as_view()), 
    url(r'^ironfaq/(?P<topic_slug>[\w-]+)/(?P<section_slug>[\w-]+)/(?P<pk>\d+)/$', 
     ArticleDetailView.as_view(), name="faq-article-detail"), 
    url(r'^ironfaq/topic/create/$', TopicCreateView.as_view()), 
    url(r'^ironfaq/section/create/$', SectionCreateView.as_view()), 
    url(r'^ironfaq/(?P<topic_pk>\d+)/article/create/$', ArticleCreateView.as_view()), 
    url(r'^ironfaq/topic/update/(?P<pk>\d+)/$', TopicUpdateView.as_view()), 
    url(r'^ironfaq/section/update/(?P<pk>\d+)/$', SectionUpdateView.as_view()), 
    url(r'^ironfaq/article/update/(?P<pk>\d+)/$', ArticleUpdateView.as_view()), 
    url(r'^ironfaq/topic/delete/(?P<pk>\d+)/$', TopicDeleteView.as_view()), 
    url(r'^ironfaq/section/delete/(?P<pk>\d+)/$', SectionDeleteView.as_view()), 
    url(r'^ironfaq/article/delete/(?P<pk>\d+)/$', ArticleDeleteView.as_view()), 
    url(r'^ironfaq/article/vote/(?P<pk>\d+)$/', ArticleVoteView.as_view()), 
] 

Le script Modèle:

{% block scripts %} 
<script> 
$(document).ready(function(){ 
    var csrftoken = Cookies.get('csrftoken'); 

    function csrfSafeMethod(method) { 
     // these HTTP methods do not require CSRF protection 
     return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 
    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
      } 
     } 
    }); 


    function post_call(vote_data){ 
     var data = {vote_type: vote_data}; 
     var id = {{ object.id }}; 
     $.ajax({ 
      url: "/ironfaq/article/vote/"+id+"/", 
      type: "POST", 
      data: data, 
     }).done(function() { 
      console.log("POST!"); 
     }); 
    } 

    var vote_up = "vote_up"; 
    var vote_down = "vote_down"; 

    var thumbs_up = $('#thumbs_up'); 
    var thumbs_down = $('#thumbs_down'); 

    thumbs_up.on('click', function(){ 
     post_call(vote_up) 
    }); 
    thumbs_down.on('click', function(){ 
     post_call(vote_down) 
    }); 
}); 
</script> 
{% endblock %} 

La vue:

class ArticleVoteView(UpdateView): 
    model = Article 
    fields = [] 

    def form_valid(self, form): 
     article = form.save(commit=False) 
     vote_type = self.request.POST.get('vote_type') 

     if vote_type == 'vote_up': 
      article.vote_up = article.vote_up + 1 
      article.save() 
     elif vote_down == 'vote_down': 
      article.vote_down = article.vote_down + 1 
      article.save() 

     data = {'status': 'success', 'vote_type': vote_type, 'yes_count': article.vote_up, 
       'total_votes': article.total_votes()} 

     return HttpResponse(json.dumps(data)) 
+0

Django n'aime pas les URL sans slash - commencez là car il peut faire des redirections. Si cela ne vous aide pas, vous pouvez toujours essayer de surcharger la méthode 'dispatch' des vues pour voir quel type de requête est en cours de construction - utilisez' pdb' dans cette méthode. – McAbra

+0

Etes-vous sûr que l'URL est traitée par cette vue? S'il vous plaît montrer vos modèles d'URL. – Alasdair

+0

Avoir fait la modification pour afficher toutes les URL. –

Répondre

0

Il ressemble à votre demande de poste à /ironfaq/article/vote/<id> est compensée par ce modèle url:

url(r'^ironfaq/(?P<topic_slug>[\w-]+)/(?P<section_slug>[\w-]+)/(?P<pk>\d+)/$', 
    ArticleDetailView.as_view(), name="faq-article-detail"), 

Depuis des vues de détail ne traitent que recevoir des demandes, votre demande de poste provoque une 405 réponse .

Vous avez besoin soit de redessiner vos modèles d'URL afin qu'ils ne se heurtent pas, ou déplacer le motif url faq-article-detail ci-dessous le modèle url vote (et tous les autres que des affrontements avec).