Django重定向,但传递形式错误上下文

时间:2016-04-03 10:47:31

标签: python django forms redirect

我有一个非常简单的索引页面视图,用户可以从中填写一个登录弹出窗口,它会向/ login发送一个帖子请求

package main

import (
    "fmt"
    "time"
    )

func main() {
    Remind("It's time to eat")
}


func Remind(text string) {
    t := time.Now()
    fmt.Println(t)
    fmt.Printf("The time is %d.%d: ", t.Hour, t.Minute)
    fmt.Printf(text)
    fmt.Println()
}

如果登录有效,它只是重定向到索引页面,这样可以正常工作。

登录视图如下所示:

def index(request):
    """Shows list of studyspaces, along with corresponding 'busyness' score"""
    context = {'study_space_list': StudySpace.objects.order_by('-avg_rating')}
    if request.user.is_authenticated():
        context['user'] = request.user
    else:
        context['login_form'] = LoginForm()
        context['user_form'] = UserForm()
        context['student_form'] = StudentForm()
    return render(request, 'spacefinder/index.html', context)

但是当登录不正确时,我希望能够刷新页面并在索引模板中显示登录表单错误(在登录弹出窗口中)

我实际上能够通过上面的代码实现这一点,但由于以下原因,我对解决方案不满意:

  • 我必须再次手动获取上下文,例如用户/学生表单和studyspace,这违反DRY原则
  • 刷新页面时,网址为def user_login(request): form = LoginForm(request.POST) if request.method == 'POST' and form.is_valid(): user = form.login(request) if user: login(request, user) return redirect(reverse('spacefinder:index')) # Load the context all over again context = { 'study_space_list': StudySpace.objects.order_by('-avg_rating') } context['login_form'] = form context['user_form'] = UserForm() context['student_form'] = StudentForm() return render(request, 'spacefinder/index.html', context)

行为here

的屏幕截图

我想知道是否有某种方法可以使用重定向来重新加载索引页面并以某种方式从我的login_form传递错误,例如类似的东西:

localhost:8000/spacefinder/login

我已经研究过使用消息来传递表单验证错误,但是由于Validation Errors被抛出到forms.py中,所以很难让它工作,我无法从ModalForm中获取请求实例来正确创建消息

1 个答案:

答案 0 :(得分:1)

你这样做是错误的。 考虑以下先决条件:

  1. 您网页的入口点是索引视图
  2. 索引视图只能由经过身份验证的用户访问
  3. 登录视图允许方法GETPOST,并且只能由匿名用户访问
  4. 使用Django的原因是利用它提供的所有功能,包括处理上述功能(因为这是大多数页面所需要的,而不仅仅是你)。

    要正确设置,您需要像这样定义urls.py

    from django.contrib.auth.decorators import login_required
    
    urlpatterns = [
        ....
        url('^login/$', user_login, 'login'),
        url('^/$', login_required(index), 'index'),
        ....
    ]
    

    settings/base.py(或settings.py,如果您没有环境差异)告诉Django如何重定向用户:

    LOGIN_URL = reverse_lazy('login')
    LOGIN_REDIRECT_URL = reverse_lazy('index')
    

    https://docs.djangoproject.com/en/1.9/ref/settings/#login-url https://docs.djangoproject.com/en/1.9/ref/settings/#login-redirect-url

    简化索引视图:

    def index(request):
        """Shows list of studyspaces, along with corresponding 'busyness' score"""
        context = {'study_space_list': StudySpace.objects.order_by('-avg_rating')}
        if request.user.is_authenticated():
            context['user'] = request.user
        else:
            return HttpResponseForbidden()  # prevented by Django, should never happen
        return render(request, 'spacefinder/index.html', context)
    

    让user_login视图提供空的登录表单:

    @require_http_methods(["GET", "POST"])
    def user_login(request):
        params = getattr(request, request.method)
        form = LoginForm(params)
        if request.method == 'POST' and form.is_valid():
            user = form.login(request)
            if user:
                login(request, user)
                return redirect(reverse('spacefinder:index'))
    
        # Load the context for new form or form with errors
        context = {
            'study_space_list': StudySpace.objects.order_by('-avg_rating')
        }
        context['login_form'] = form
        context['user_form'] = UserForm()
        context['student_form'] = StudentForm()
        return render(request, 'spacefinder/index.html', context)
    

    您尚未提供任何处理UserFormStudendForm的代码。您还需要将其添加到user_login视图中 - 如果这是所有用户每次登录时都应填写的内容。否则使用不同的视图。

    值得研究像allauth这样的模块。在允许用户使用他们的电子邮件地址登录时,他们可能会为您节省一些工作,确定电子邮件地址在系统中是唯一的等。