如何在Django

时间:2019-04-10 08:36:34

标签: django python-3.x django-forms django-views

我正在创建一个应用,我想在其中使用自己的自定义登录表单和验证码字段。我的目的是在不使用外部库(请求除外)的情况下执行此操作,但是我无法在forms.py的自定义表单中添加验证码字段,因此出于某种原因将其直接添加到login.html当我执行form.is_valid()时会返回错误。

我已经在Django - adding google recaptcha v2 to login formAdding a Recaptcha form to my Django login page中看到了解决方案,但是正如我所说,我想不使用外部库就可以做到这一点。

views.py

...

def login_view(request):
    if request.method == 'POST':
        form = CustomLoginForm(request.POST)

        result = is_recaptcha_valid(request)
        print(result) # prints True

        if form.is_valid():

            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']

            user = authenticate(request, username=username, password=password)

            if user is not None:
                login(request, user)

                # Redirect to index
                messages.success(request, "Logged in.")
                return HttpResponseRedirect(reverse('orders:index'))
            else:
                messages.error(request, "Invalid credentials.")
        else:
            print("error")
            return render(request, 'registration/login.html', {'form': CustomLoginForm()})

    else:
            form = CustomLoginForm()
    return render(request, 'registration/login.html', {'form': form})

forms.py

class CustomLoginForm(AuthenticationForm):
    email = forms.EmailField(
        error_messages={
            'required': 'Please enter your email.',
            'invalid': 'Enter a valid email address.'
        },
        help_text='Email',
    )

login.html

  <form class="" action="{% url 'orders:login' %}" method="post">
    {% csrf_token %}
    {% for field in form %}
      <p>
        {{ field.label_tag }}<br>
        {{ field }}
        {% if field.help_text %}
          <small style="color: grey">{{ field.help_text }}</small>
        {% endif %}
        {% for error in field.errors %}
          <p style="color: red">{{ error }}</p>
        {% endfor %}
      </p>
    {% endfor %}

    <!-- ReCAPTCHAV3 -->
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>

    <div class="g-recaptcha" data-sitekey='key-here'></div>
    <button class="btn btn-success" type="submit" name="">Login</button>
    <!-- <input type="hidden" name="next" value="{{ next }}"> -->
  </form>

is_recaptcha_valid()函数已经返回True,所以我没有分享。我是Django的初学者,所以如果您能用两个词解释我做错了什么,而不仅仅是发布答案,我将不胜感激。谢谢您的宝贵时间。

1 个答案:

答案 0 :(得分:1)

AuthenticationForm与其他的略有不同。

如果您的支票AuthenticationForm类,则AuthenticationForm的第一个参数不是 data ,就像其他形式一样:

class AuthenticationForm(forms.Form):
    ...

    def __init__(self, request=None, *args, **kwargs):
        ...

这就是为什么您需要将 request.POST 传递给 data

所以像这样更新您的代码:

def login_view(request):
    if request.method == 'POST':
        form = CustomLoginForm(data=request.POST)
        ...