Running Django 4.1.1. Having this code below in template. By clicking a button it sends a data to delete apropriate marker.
<form method="POST">
{% csrf_token %}
<ol>
{% for marker in markers %}
<li>
{{ marker }} - <button id="delete" value="{{ marker.pk }}" type="submit">Delete</button>
</li>
{% endfor %}
</ol>
</form>
In views.py
def user_markers(request):
markers = Marker.objects.filter(owner_id=request.user.id).select_related()
if request.method == "POST":
print(request.POST.get("delete")) # gives me None
marker = Marker.objects.get(pk=request.POST.get("delete"))
marker.delete()
context = {
"markers": markers,
}
return render(request, "hub/markers.html", context)
The problem is that request.POST.get("delete") is empty. POST data has only 'csrfmiddlewaretoken' Do I miss something?
CodePudding user response:
You need to specify this as name, so:
<button id="delete" name="delete" value="{{ marker.pk }}" type="submit">Delete</button>
If you do not specify a name, it will not be include in the POST data, and thus it will not contain any value that is passed with the button.
You might want to improve the view function:
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect
@login_required
def user_markers(request):
markers = Marker.objects.filter(owner_id=request.user.id).select_related()
if request.method == 'POST':
get_object_or_404(
Marker, owner=request.user, pk=request.POST.get('delete')
).delete()
return redirect('name-of-some-view') # need to redirect
context = {
'markers': markers,
}
return render(request, 'hub/markers.html', context)
Note: In case of a successful POST request, you should make a
redirect
[Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
Note: It is often better to use
get_object_or_404(…)
[Django-doc], then to use.get(…)
[Django-doc] directly. In case the object does not exists, for example because the user altered the URL themselves, theget_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using.get(…)
will result in a HTTP 500 Server Error.