0

I have a fixed navigation and I want to add dropdown box where users can singup\in (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?

TitanFighter
  • 4,582
  • 3
  • 45
  • 73
  • Can you include your view in the post? – Michael Fourre Aug 29 '16 at 02:25
  • @MichaelFourre, it seems that here there is a problem. I found at SO (example - http://stackoverflow.com/questions/29499449/django-allauth-login-signup-form-on-homepage ) and in internet ( http://notesbyanerd.com/joint-login-and-signup-django-allauth-view ) some views samples, but I have no idea how to connect them to dropdown form. Original views are here - https://github.com/pennersr/django-allauth/blob/master/allauth/account/views.py – TitanFighter Aug 29 '16 at 02:30
  • But where is your view? Are you using the SignupView as a parent class? – Michael Fourre Aug 29 '16 at 02:32
  • @MichaelFourre, lets take for example the view that is already written at another SO thread. How to combine that view with dropdown menu? – TitanFighter Aug 29 '16 at 02:37
  • Why don't you want to add your view? We can tell you how something might work with a view from another SO post but that might not be how it works in your situation. For one, since you can clearly see `login_form` is the name of the LoginForm instance, you'll refer to it as `login_form` in the view rather than `signupform` as you have. But I doubt your view uses the same name, so just post your view? – Michael Fourre Aug 29 '16 at 02:40
  • @MichaelFourre, sorry that I disturb you. Could you explain few things to me pls. 1. I do not understand, why I need to make my own views. Why I cant use `allauth` views directly? I do not want to change anything in `allauth`. I simpy want to move its template or form from separate page as `account/signup` to nav bar. 2. In order to get any apps form, it is needed to call views via url. I do not know, how to make this call to view from nav bar in order to get as a responce template or form. I want to have signup\login template\form as a dropdown block (not a link) on every site's page. – TitanFighter Aug 30 '16 at 00:20

1 Answers1

11

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 username\password 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 signin\up forms to default AllAuth views can be found ->here<-. If anyone could implement it, or find any tutorial, please post it here.

Community
  • 1
  • 1
TitanFighter
  • 4,582
  • 3
  • 45
  • 73