2016-04-03 56 views
1

我有一個很簡單的索引頁視圖,從該用戶可以在登錄彈出,它發送POST請求填到/登錄Django的重定向,但傳遞形式的錯誤上下文

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) 

如果登錄有效它只是重定向到索引頁,這工作正常。

登錄視圖如下所示:

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) 

但是當登錄不正確我希望能夠刷新頁面,並顯示該指數模板中的登錄表單錯誤(在登錄彈出)

我居然能與上面的代碼來實現這一點,但我很不滿,原因如下解決方案:

  • 我必須手動一遍獲取上下文,如用戶/學生的形式和studyspaces,這違背了DRY原則
  • 當頁面被刷新的URL是行爲的localhost:8000/spacefinder/login

截圖here

我想知道是否有某種方式使用重定向重新加載索引頁,並以某種方式傳遞我的login_form錯誤,例如是這樣的:

return redirect('spacefinder:index', {'login_form': form}) 

我已經研究過使用信息傳遞形式驗證錯誤,但奮鬥因爲驗證錯誤在裏面forms.py扔得到這個工作,我無法從獲取請求實例在ModalForm中正確地創建一條消息

回答

1

你正在這樣做是錯誤的。 考慮以下先決條件:

  1. 入口點到您的網頁索引視圖
  2. 索引視圖只需通過身份驗證的用戶
  3. 登錄視圖允許被訪問兩種方法GETPOST,並且是匿名訪問用戶只有

使用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。當允許用戶使用他們的電子郵件地址登錄,確定電子郵件地址在系統中是唯一的時候,他們可能會讓你省下一些工作。

+0

我的頁面的入口點是索引視圖,但是我'非常喜歡未經認證的用戶能夠看到索引頁面。然後讓他們能夠從索引頁面登錄 –

+0

在這種情況下,可以將'user_login'和'index'的代碼移動到一個視圖中,或通過'AJAX POST'調用'user_login'並僅替換登錄部分與返回的HTML(您可以使用只返回表單的HTML的部分模板,包括錯誤)。 – Risadinha

+0

我認爲結合登錄和索引視圖可能是最好的解決方案。非常感謝您的幫助! –