【问题标题】:Django: Change url based on result of user authenticationDjango:根据用户身份验证的结果更改 url
【发布时间】:2017-05-07 10:17:00
【问题描述】:

我是 django 的新手,被我认为是一个简单的问题所困扰。我已经在我的应用程序中设置了用户身份验证,它工作正常,我遇到的问题是提交表单时出现的 url 地址。问题来了:

我的表单上接收用户登录凭据的操作设置为"{% url 'home' %}",这是对/dashboard/home 的引用。这正是我希望成功登录时的 url。但是,当登录不成功时,我想留在登录网址上,即/dashboard/login。正如您可以想象的那样,发生的事情是在登录失败的情况下,url 仍然更改为/dashboard/home。我认为这对用户具有误导性,通常只是不好的做法,但我不知道如何根据登录尝试的结果动态更改 url。尝试不成功时如何将 url 更改为/dashboard/login,但成功时将其保留为/dashboard/home?

我的文件

HTML 模板

截断为仅形式。

        <form method="POST" action="{% url 'home' %}">
            {% csrf_token %}
            <div class="form">
                <label for="email" class="credentials">Email:</label>
                <input type="text" name="email" id="email" size="12" maxlength="30" />
            </div>
            <div class="form">
                <label for="password" class="credentials">Password:</label>
                <input type="password" name="password" id="password" size="12"
                    maxlength="30" />
            </div>
            <div class="submit">
                <input type="submit" name="submit" value="GET STARTED" />
            </div>
        </form>

观看次数

请原谅所有的打印函数,它们对初学者有帮助 :) 我还使用了一些通过上下文字典传递给模板的变量,这些变量我还没有从视图中删除(例如, “登录成功”)

def portal(request):
if request.method == 'POST':
    print ("first if was executed")
    form = AuthenticationForm(request.POST)

    if form.is_valid():
        print ("second if was executed")
        username = request.POST['email']
        password = request.POST['password']
        user = authenticate(username=username, password=password)

        if user is not None:
            print("user authenticated")

            if user.is_active:
                print("user active")
                login_successful = 1
                print('login_successful: ',login_successful)
                login(request, user)
                d = (UserFields.objects.filter(userid__exact=username).values())

                d2 = d[0]
                print(d2)
                m = d2["manager"]
                am = d2["apexmanager"]
                print (m)
                print (am)
                if am==True:
                    print ("apex executed")
                    return render(request, 'dashboard/homeApexManager_new.html', {'login_error': login_successful})

                elif m==True:
                    print ("m true executed")
                    return render(request, 'dashboard/homeManager_new.html', {'login_error': login_successful})

                else:
                    print ("m false executed")
                    return render(request, 'dashboard/homeEmployee_new.html', {'login_error': login_successful})

            else:
                print("not active")
                return render(request, 'dashboard/login.html')

        else:
            print ("not authenticated")
            login_error = 1
            print (login_error)
            return render_to_response('dashboard/login.html', {'login_error': login_error})

    else:
        print ("form is not valid")
        login_error=1
        print (login_error)
        return render_to_response('dashboard/login.html', {'login_error': login_error})

else:
    print ("request is not POST")
    return render(request, 'dashboard/login.html', {'form': form})            

网址

from django.conf.urls import url
from . import views
from django.contrib.auth import views as auth_views

urlpatterns = [
    url(r'^login', auth_views.login,name = 'login'),
    url(r'^home', views.portal,name = 'home'),
        ]

【问题讨论】:

  • 你能展示你的观点吗?和完整的html
  • 您可能希望将操作提交到 /dashboard/login。你会有一些像if request.method == "POST": 这样的东西。在那里,如果正确的凭据被重定向到HttpResponseRedirect(reverse('home')),如果没有,视图应该再次显示登录表单。类似于文档中描述的方式:docs.djangoproject.com/en/1.10/topics/forms/#the-view
  • @AMG,感谢您的建议——现在查看 reverse()。

标签: django django-forms url-redirection django-urls django-authentication


【解决方案1】:

正如 AMG 在他的评论中提到的,RightThing(tm) 要做的是在您的登录视图中处理表单提交 (POST),然后重定向到 dashbord 主页 url(如果表单有效并且登录成功)如果表单无效或登录失败,则重新显示表单(不重定向)。作为一般规则,这里是处理表单提交的规范方法(除了应该使用 GET 方法并且从不重定向的搜索表单):

def someformview(request, ...): 
    if request.method == "POST":
        # the user submitted the form, let's validate it
        form = SomeFormClass(request.POST)
        if form.is_valid():
            # ok, process the data and redirect the user
            do_something_with(form.cleaned_data)
            return redirect("someapp:anotherview")
        # if form is not valid just redisplay it again
        # so the user gets the error messages
    else:
        # assume a GET request: create an unbound form
        form = SomeFormClass()

   # we either had a GET request or invalid form, 
   # let's display it     
   return render(request, "someapp/someviewtemplate.html", {form:form})

【讨论】:

  • 谢谢你,布鲁诺。我的表单上的操作应该是什么?我有行动吗?
  • 当然,帖子应该提交到相同的视图(相同的 url)——如果你省略了“action”属性,这是默认设置。
【解决方案2】:

据我了解,您的表单在用户主页上重定向用户,无论表单是否有效。

所以你不需要使用action="{% url 'home' %}"重定向用户这意味着当提交表单时页面必须重定向主页上的用户,无论它是否成功登录。

您必须使用您的视图进行重定向。下面我留下了cmets的例子,希望对你有帮助:

def portal(request):
  form = AuthenticationForm(request.POST)
  if request.method == 'POST': # checkout if method POST
    print ("first if was executed")
    if form.is_valid(): #checkout if form is valid
        print ("second if was executed")
        username = request.POST['email']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        return HttpResponseRedirect('/dashboard/home/') #if form is valid, it redirect user on home page
    else:
        return render(request, 'dashboard/login.html', {'form': form}) # if not valid it render this form on the same page
  else: # if method GET we just render the form
    print ("request is not POST")
    return render(request, 'dashboard/login.html', {'form': form}) 

希望对你有帮助。

更新

action 是提交表单后重定向页面的 url。因此,如果您将使用与我上面写的相同的视图,则不需要操作 url,只需保留它action="."

【讨论】:

  • 谢谢你,扎戈罗德尼。我对你有同样的问题,就像我在下面对布鲁诺所做的一样。我的表单上的操作应该是什么?我有行动吗?
猜你喜欢
  • 2017-07-05
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 2010-12-23
  • 1970-01-01
相关资源
最近更新 更多