Django login from in modal window

2019-04-10 04:11发布

问题:

I have a login form and I want to put in modal window in header.

Urls.py

url(r'^account/login/$', appuser_views.LoginView.as_view(template_name = 'account/login/index.html', form_class = appuser_forms.LoginForm, target_url = LOGIN_TARGET_URL)),

views.py

class LoginView(ResendEmailToUsersMixin, AjaxFormView):

    def process_form(self, request, form):
        data = form.cleaned_data

        a = AppUserCredential.objects.select_related('appuser').filter(
                data1 = data['email_address'],
                credential_type = AppUserCredential.CREDENTIAL_TYPES.EMAIL_PASSWORD,
                appuser__status = AppUser.STATUS_TYPES.Active
            ).first()

        force_error = False
        if a is None:
            response = self.resend_email_to_users(data = data)
            if response is not None:
                return response
            #If no email exists force the error and don't check the password
            force_error = True

        if force_error or not a.check_password(data['password']):
            return AjaxErrorResponse(code="login_error", title="Username or Password Error", message="The username or password you have provided don’t match our records. Please check your entries and try again.")

        a.appuser.login(request)

forms.py

class LoginForm(AjaxForm):
    email_address = forms.EmailField(label = "Email Address", required = True, max_length = 100,
                    widget = forms.TextInput(attrs = {'placeholder': 'email@domain.com', 'autocomplete':'off'}))
    password = forms.CharField(label = "Password", required = True, max_length = 100,
                    widget = forms.PasswordInput(attrs = {'placeholder': 'Password', 'autocomplete':'off'}))

    def setup_form_helper(self, helper):
        helper.form_id = 'login_form'
        helper.layout = Layout(
            'email_address',
            'password',
            Div(
                Submit('submit', 'Login', css_class='btn btn-primary'),
                css_class="form-group text-center"
                ),
            HTML('<p class="pull-right light-top-bottom-padding"><a href="/account/forgot-password" title="Forgot Password">Forgot Password?</a></p>')
            )

/templates/account/login/index.html

...
{% crispy form form.helper %}
...

I have created modal window in /templates/layouts/header.html How can I put {% crispy form form.helper %} in the modal window? Thanks.

UPD1: If I put {% crispy form form.helper %} in header.html I got the error

VariableDoesNotExist at / Failed lookup for key [form] in u'[{\'False\': False, \'None\': None, \'True\': True},

UPD2: Modal form:

    <a href="javascript:void(0);" class="text-btn" data-toggle="modal" data-target="#login">login</a>

        <div id="login" class="modal fade" role="dialog">
          <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Modal Header</h4>
              </div>
              <div class="modal-body">
                    <p>Some text in the modal.</p>
                    <div class="panel-body">
                        <header class="section-title text-center normal-top-bottom-padding">
                            <h1>Login</h1>
                        </header>
                    </div>

              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
              </div>
            </div>

          </div>
        </div>

Link to login should be in every page.

回答1:

If you want to display the form in all pages, you need to add the form (better call it login_form so it doesn't conflict with other forms you may have) to every View's context.

To avoid doing that repeatedly in all Views, Django has Context Processors. You include them in settings.py's TEMPLATES variable. Example

TEMPLATES = [{
    ...
    'OPTIONS': {
        'context_processors': [
            ...
            'myapp.context_processors.add_my_login_form',
        ],
    }]

Then, create a file called context_processors.py and add the add_my_login_form() function in there. The function returns the login_form to the request context of all requests.

def add_my_login_form(request):
    return {
        'login_form': LoginForm(),
    }

Since you are rendering the form in every page, it maybe good to use template caching.