Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

django - How to move singupsignin templates into dropdown menu?

I have a fixed navigation and I want to add dropdown box where users can singupin (as Twitter uses).

I tried:

# project/tempates/signup.html
{% load i18n %}
{% load account socialaccount %}

{% block head_title %}{% trans "Signup" %}{% endblock %}

{% block content %}

  <h1>{% trans "Sign Up" %}</h1>

  <p>{% blocktrans %}Already have an account? Then please <a href="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>

  <form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
    {% csrf_token %}
    {{ signupform.as_p }}
    {% if redirect_field_value %}
    <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
    {% endif %}
    <button type="submit">{% trans "Sign Up" %} &raquo;</button>
  </form>

{% endblock %}

# project/tempates/base.html
# ... a lot of basic stuff
<li class="dropdown">
    <a class="dropdown-toggle" href="#" data-toggle="dropdown">Sign In <strong class="caret"></strong></a>
    <div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px;">
        {% include './signup.html' %}
# ... rest stuff

and in dropdown box I see just the text, link to signin, and the button for confirmation of the registration.

There are no fields to enter email and passwords. As I understand, this is because no access to the form, what usually is a views' jobs. How can I get workable dropdown forms?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

After 2 days of internet digging I want to summarize what I found.

There are few ways:

1. Use <form action='some address here'>. The easiest way.

To check default AllAuth forms we need to:

# ./manage.py shell
>>> import allauth.account.forms as forms
>>> f = forms.LoginForm()
>>> print(f)

Below is edited version of print(f) which is added directly to base.html

<form action="{% url 'account_login' %}" method="post">
    {% csrf_token %}
    <input type="hidden" name="next" value="{{ request.get_full_path }}" />

    <input id="id_login" name="login" placeholder="Username or e-mail" type="text" required />
    <input id="id_password" name="password" placeholder="Password" type="password" required />

    <label for="id_remember">Remember Me:</label>
    <input id="id_remember" name="remember" type="checkbox" />

    <button type="submit">Login</button>
    <a href="{% url 'account_reset_password' %}">Forgot Password?</a>
</form>

Method is based on the solution from ->here<-

2. Contex processor

a) Make folder your_project/your_app/context_processor. Put there 2 files - __init__.py and login_ctx.py

b) In login_ctx.py add:

from allauth.account.forms import LoginForm

def login_ctx_tag(request):
    return {'loginctx': LoginForm()}

c) In project's SETTINGS add your_app.context_processors.login_ctx.login_form_ctx' inTEMPLATES` section. Something like:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates', 'allauth')],
        'APP_DIRS': True,
        'OPTIONS': {
            'debug': DEBUG,
            'context_processors': [
                'your_app.context_processors.login_ctx.login_form_ctx',  # <- put your processor here 
                'django.template.context_processors.debug',
                # [...other processors...]
            ],
        },
    },
]

d) In your *.html where you need add the next:

{% if not user.is_authenticated %}
    <form action="{% url 'account_login' %}" method="post">
        {% csrf_token %}
        <input type="hidden" name="next" value="{{ request.get_full_path }}" />
        {{ loginctx }}
        <button type="submit">Login</button>
    </form>
{% else %}
    {# display something else here... (username?) #}
{% endif %}

3. Template tag

a) Make folder your_project/your_app/templatetags. Put there 2 files - __init__.py and login_tag.py

b) In login_tag.py add:

from django import template
from allauth.account.forms import LoginForm

register = template.Library()

@register.inclusion_tag('profiles/true_login.html')
def login_form_tag(current_page=None):
    return {'loginform': LoginForm(),
            'redirect_to': current_page}

c) In your_project/your_app/templates/your_app/ make file login_form.html with content:

{% load account  %}

{% if not user.is_authenticated %}
    <form action="{% url 'account_login' %}" method="post">
        {% csrf_token %}
        <input type="hidden" name="next" value="{{ redirect_to }}" />
        {{ loginform }}
        <button type="submit">Login</button>
    </form>
{% else %}
    {# display something else here... (username?) #}
{% endif %}

d) In any *.html you need, add at the top {% load login_tag %} and in the needed place add {% login_form_tag request.get_full_path %}


The 2nd and 3rd methods show native AllAuth form. If you need to edit it somehow using {{form}}, ->here<- in the doc you can find some examples how to do that. Want to mention, that if in the doc is shown something like:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
</div>

for our case form must be changed to loginctx or loginform

Also you can write your own form or inherit AllAuth and import it to context processor or templatetag as shown above.

Both methods are based on ->this solution<-

In all 3 methods redirect works as needed (return a user to the previous page, in case of success login, else redirect to original AllAuth template at site.com/account/login).

All written above can be implemented to SignUP.

Also I asked some people, how to show errors in case of wrong usernamepassword instead of redirect to site.com/account/login, a proposition was to use AJAX, but currently this is out of my knowledge. Some base info about connection signinup forms to default AllAuth views can be found ->here<-. If anyone could implement it, or find any tutorial, please post it here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...