1

Django 1.10

DetailView renders "detail.html".

In "detail.html" I place "Delete" button. In other words, I want users to be able to press "Delete" exactly from "detail.html" when they see the object itself.

So, on pressing "Delete" button I call FrameDelete via AJAX.

Could you help me understand why I get the error: CSRF token missing or incorrect.

class Frame(models.Model): title = models.CharField(max_length=100, null=False, blank=False, default="", unique=True, verbose_name="Заголовок") def get_delete_url(self): return reverse("frame:frame_delete", kwargs=self.get_kwargs()) class FrameDelete(ActionDeleteMixin, DeleteView): model = Frame success_url = reverse_lazy("empty") template_name = 'general/ajax/ajax_confirm_delete.html' class ActionDeleteMixin(): def get_context_data(self, **kwargs): context = super(ActionDeleteMixin, self).get_context_data(**kwargs) context["action"] = self.object.get_delete_url() return context 

js

 function post_delete(){ $.ajax({ method: 'POST', url: "{{ object.get_delete_url }}", success: redirect_to_frame_list, error: fail }); } function fail(jqXHR, textStatus, errorThrown){ debugger; } 

ajax_confirm_delete.html

{% block content %} <form action="{{ action }}" method="post">{% csrf_token %} <p>Are you surely want to delete "{{ object }}"?</p> <input id="confirm" type="submit" value="Confirm" /> </form> {% endblock %} 

In the browser when inspecting element in Chrome:

<form action="/frame/18/delete/" method="post"><input type="hidden" name="csrfmiddlewaretoken" value="bHZxf62Oa9WrapuacCm8gLVNlY2nJHllfwqPsAHoPO0RS8z8NnhMSv5tnIFQZKPP"> <p>Are you surely want to delete "18: Michael's news"?</p> <input id="confirm" type="submit" value="Confirm"> </form> 

**

In the browser when stop at the debugger breakpoint in fail function

" <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="robots" content="NONE,NOARCHIVE"> <title>403 Forbidden</title> <style type="text/css"> html * { padding:0; margin:0; } body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; background:#eee; } body>div { border-bottom:1px solid #ddd; } h1 { font-weight:normal; margin-bottom:.4em; } h1 span { font-size:60%; color:#666; font-weight:normal; } #info { background:#f6f6f6; } #info ul { margin: 0.5em 4em; } #info p, #summary p { padding-top:10px; } #summary { background: #ffc; } #explanation { background:#eee; border-bottom: 0px none; } </style> </head> <body> <div id="summary"> <h1>Forbidden <span>(403)</span></h1> <p>CSRF verification failed. Request aborted.</p> </div> <div id="info"> <h2>Help</h2> <p>Reason given for failure:</p> <pre> CSRF token missing or incorrect. </pre> <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when <a href="https://docs.djangoproject.com/en/1.10/ref/csrf/">Django's CSRF mechanism</a> has not been used correctly. For POST forms, you need to ensure:</p> <ul> <li>Your browser is accepting cookies.</li> <li>The view function passes a <code>request</code> to the template's <a href="https://docs.djangoproject.com/en/dev/topics/templates/#django.template.backends.base.Template.render"><code>render</code></a> method.</li> <li>In the template, there is a <code>{% csrf_token %}</code> template tag inside each POST form that targets an internal URL.</li> <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use <code>csrf_protect</code> on any views that use the <code>csrf_token</code> template tag, as well as those that accept the POST data.</li> <li>The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login.</li> </ul> <p>You're seeing the help section of this page because you have <code>DEBUG = True</code> in your Django settings file. Change that to <code>False</code>, and only the initial error message will be displayed. </p> <p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p> </div> </body> </html> " 

1 Answer 1

2

You should add the csrf_exempt or generate the csrf token with ajax

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.