如何通过URL制定禁止入内,如果它不是由项目的“名称”创建的。

huangapple go评论85阅读模式
英文:

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

&lt;div class=&quot;is__done__checkbox&quot;&gt;
    &lt;form method=&quot;post&quot; action=&quot;{% url &#39;done&#39; task.pk %}&quot;&gt;
    {% csrf_token %}
    &lt;input type=&quot;checkbox&quot; name=&quot;is_done&quot; onchange=&quot;this.form.submit()&quot; {% if task.is_done %} checked {% endif %}&gt;
    &lt;/form&gt;
&lt;/div&gt;

url

path(&#39;profile/&lt;int:pk&gt;/done/&#39;, done, name=&#39;done&#39;),

view

def done(request, pk):
    task = Tasks.objects.get(pk=pk)
    is_done = request.POST.get(&#39;is_done&#39;, False)
    if is_done == &#39;on&#39;:
        is_done = True

    task.is_done = is_done
    task.save()
    return redirect(request.META.get(&#39;HTTP_REFERER&#39;))

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(&#39;/profile/&lt;int:pk&gt;/done/&#39;)
def done(request, pk):
    task = Tasks.objects.get(pk=pk)
    is_done = request.POST.get(&#39;is_done&#39;, False)
    if is_done == &#39;on&#39;:
        is_done = True

    task.is_done = is_done
    task.save()
    return redirect(request.META.get(&#39;HTTP_REFERER&#39;))

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&nbsp;<sup>[Django-doc]</sup>:

<pre><code>from django.views.decorators.http import <b>require_POST</b>

@login_excluded('/profile/&lt;int:pk&gt;/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(&hellip;)</code>&nbsp;<sup>[Django-doc]</sup>,
> then to use <code>.get(&hellip;)</code>&nbsp;<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(&hellip;)</code> will result in returning a HTTP 404 Not Found response, whereas using
> <code>.get(&hellip;)</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 == &quot;POST&quot;:
    task = Tasks.objects.get(pk=pk)
    is_done = request.POST.get(&#39;is_done&#39;, False)
    if is_done == &#39;on&#39;:
        is_done = True

    task.is_done = is_done
    task.save()
    return redirect(request.META.get(&#39;HTTP_REFERER&#39;))
else:
    #If the user has just typed the URL (eg, method==&quot;GET&quot;), then do something else
    return redirect(&#39;/formerror&#39;)

huangapple
  • 本文由 发表于 2023年4月11日 05:05:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定