英文:
How to make a ban on entering by url, if it was not made by the item "name"
问题
I have a small function that controls the checkbox. When the user clicks on the checkbox, this link is triggered by {% url 'done' task.pk %}. But if you try to open this link in another tab, the checkbox also switches.
如何使用户能够通过"value"跟随链接,但是当他手动输入URL时会出现错误。或者解决这个问题的替代方法。
Code
<div class="is__done__checkbox">
<form method="post" action="{% url 'done' task.pk %}">
{% csrf_token %}
<input type="checkbox" name="is_done" onchange="this.form.submit()" {% if task.is_done %} checked {% endif %}>
</form>
</div>
URL
path('profile/<int:pk>/done/', done, name='done'),
View
def done(request, pk):
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
I tried it
def login_excluded(redirect_to):
def _method_wrapper(view_method):
def _arguments_wrapper(request, *args, **kwargs):
if request.user:
return HttpResponse(status=404)
return view_method(request, *args, **kwargs)
return _arguments_wrapper
return _method_wrapper
@login_excluded('/profile/<int:pk>/done/')
def done(request, pk):
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
But when clicking on the checkbox and for the user there was an error.
英文:
I have a small function that controls the checkbox. When the user clicks on the checkbox, this link is triggered by {% url 'done' task.pk %}. But if you try to open this link in another tab, the checkbox also switches.<br>
How to make the user be able to follow the link by the value "name", but when he manually enters the url, there would be an error. Well, or some alternative solution to this problem.<br>
<b>Code</b>
template
<div class="is__done__checkbox">
<form method="post" action="{% url 'done' task.pk %}">
{% csrf_token %}
<input type="checkbox" name="is_done" onchange="this.form.submit()" {% if task.is_done %} checked {% endif %}>
</form>
</div>
url
path('profile/<int:pk>/done/', done, name='done'),
view
def done(request, pk):
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
I tried it
def login_excluded(redirect_to):
def _method_wrapper(view_method):
def _arguments_wrapper(request, *args, **kwargs):
if request.user:
return HttpResponse(status=404)
return view_method(request, *args, **kwargs)
return _arguments_wrapper
return _method_wrapper
@login_excluded('/profile/<int:pk>/done/')
def done(request, pk):
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
But when clicking on the checkbox and for the user there was an error
答案1
得分: 1
但如果您尝试在另一个选项卡中打开此链接,则复选框也会切换。
您的视图不会阻止通过GET请求访问它。您可以使用 @require_POST
装饰器:
from django.views.decorators.http import require_POST
@login_excluded('/profile/<int:pk>/done/')
@require_POST
def done(request, pk):
task = Tasks.objects.get(pk=pk)
task.is_done = request.POST.get('is_done', False) == 'on'
task.save()
return redirect(request.META.get('HTTP_REFERER'))
注意:通常更好使用 get_object_or_404(...),而不是直接使用 .get(...)。如果对象不存在,例如因为用户自行更改了URL,
get_object_or_404(...)
将返回 HTTP 404 Not Found 响应,而使用.get(...)
将导致 HTTP 500 Server Error。
英文:
> But if you try to open this link in another tab, the checkbox also switches.
Your view does not prevent accessing it through a GET request. You can use the @require_POST
decorator <sup>[Django-doc]</sup>:
<pre><code>from django.views.decorators.http import <b>require_POST</b>
@login_excluded('/profile/<int:pk>/done/')
<b>@require_POST</b>
def done(request, pk):
task = Tasks.objects.get(pk=pk)
task.is_done = request.POST.get('is_done', False) == 'on'
task.save()
return redirect(request.META.get('HTTP_REFERER'))</code></pre>
> Note: It is often better to use <code>get_object_or_404(…)</code> <sup>[Django-doc]</sup>,
> then to use <code>.get(…)</code> <sup>[Django-doc]</sup> directly. In case the object does not exists,
> for example because the user altered the URL themselves, the <code>get_object_or_404(…)</code> will result in returning a HTTP 404 Not Found response, whereas using
> <code>.get(…)</code> will result in a HTTP 500 Server Error.
答案2
得分: 1
你可以这样做,以确保用户必须通过表单提交数值:
def done(request, pk):
# 检查页面请求是否来自已提交的表单
if request.method == "POST":
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
else:
# 如果用户只是输入了URL(例如,method=="GET"),则执行其他操作
return redirect('/formerror')
英文:
You could make it so that the user has to have submitted the value via the form:
def done(request, pk):
#check to see the page request is a submitted form
if request.method == "POST":
task = Tasks.objects.get(pk=pk)
is_done = request.POST.get('is_done', False)
if is_done == 'on':
is_done = True
task.is_done = is_done
task.save()
return redirect(request.META.get('HTTP_REFERER'))
else:
#If the user has just typed the URL (eg, method=="GET"), then do something else
return redirect('/formerror')
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论