Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Over-riding Django-allauth login/ registration urls with custom url/ pages

I have configured django-allauth for login through Facebook, Twitter and Google.

However, django-allauth accepts login request only at /accounts/login/, sign up request only at /accounts/signup/ etc. I have a modal form for login and registration on my home page and I want to use only that.

enter image description here

How do I use django-allauth system to allow login ( both social and custom)/ registration etc from the modal form on my home page? I'm looking for mechanism to override django-allauth's urls and substitute them with my pages/ urls.

The code is here

The modal form HTML is here.

This question is perhaps similar to this. However the answer in the question isnt too understandable.

Following a few answers, I have made these changes:

#views.py
def logreg(request):
    context = {
        'login_form': MyLoginForm(), 
        'signup_form': MySignupForm()
    }
    return render(request, 'login.html', context)

#In URL Patterns of urls.py
url(r'^login/', logreg, name='login'),

In Index ( from where call to the modal is to be made):
<p>Welcome visitor <a href="#" data-modal-url="{% url 'login' %}">Login</a> or <a href="#">Register</a></p>

All this work resulted in this mess:

    Internal Server Error: /login/
    Traceback (most recent call last):
...
    django.core.urlresolvers.NoReverseMatch: Reverse for 'ecomweb.home' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []

During handling of the above exception, another exception occurred:

...
django.core.urlresolvers.NoReverseMatch: Reverse for 'home' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []

I'm nuts to what is happening.

like image 765
FlyingAura Avatar asked Jun 30 '16 14:06

FlyingAura


3 Answers

Well, it is pretty easy solution.

in urls.py do this:

from allauth.account.views import LoginView, SignupView 

urlpatterns = [
   ...
   url(r'^customurl/login/', LoginView.as_view(), name="custom_login" ),
   url(r'^customurl/signup/', SignupView.as_view(), name="custom_singup" ),
   ...

]

and in html create form:

<form action="{% url 'custom_signup' %}" method="POST">
  {{ form.as_p }}
</form>


<form action="{% url 'custom_login' %}" method="POST">
  {{ form.as_p }}
</form>
like image 100
Vlad Avatar answered Nov 20 '22 18:11

Vlad


For using allauth's login or signup functionality, you do not have to override urls associated with it.

Just submit your form to the urls associated with the allauth like

<form action="/accounts/login/?next{{request.path}}" method="POST">
  {% csrf_token %}
  <!-- Your form elements here -->
</form>

<form action="/accounts/signup/?next{{request.path}}" method="POST">
  {% csrf_token %}
  <!-- Your form elements here -->
</form>

Its upto you to use ?next{{request.path}}, if you want your user to stay on the same page from where he logged in.

Updated Answer:

First of all don't store templates inside the static folder, its not a good practice.

As I already pointed out that for using allauth's views functionality, you don't necessarily have to override its url and views (unless for specific reasons).

  1. Inside your templates folder create a new folder account with login.html file.
  2. Paste your html login code in this login.html file.

  3. Delete your method custom login method logreg and its related url and imports.

  4. Change all references that point to your custom login method logreg with account_login (allauth's login name).

  5. In your base.html - replace {% static 'login.html' %} to {% url 'account_login' %}.

And you are ready to go.

But you have to handle the html for the case when a user tries to visit /accounts/login/ page.

Moreover you can always use thefallback approach to submit your modal login form via ajax request to accounts/login/ and handle success() and error().

like image 3
kapilsdv Avatar answered Nov 20 '22 19:11

kapilsdv


I think you may want to call django-allauth's forms in your home view

In views.py:

from django.allauth.account.forms import LoginForm, SignupForm

def home(request):
    context = {
        'login_form': LoginForm(),
        'signup_form': SignupForm(),
    }
    return render(request, "myapp/home.html", context)

In your home template (e.g. templates/myapp/home.html):

<form action="{% url 'account_login' %}?next={% url 'home' %}" method="POST">
    {% csrf_token %}
    {{login_form}}
</form>
<form action="{% url 'account_signup' %}?next={% url 'home' %}" method="POST">
    {% csrf_token %}
    {{login_form}}
</form>

Then the last thing is that you'll have Django-allauth's blank templates by default, but you can override them by creating a base.html template in a directory called account your application template directory (e.g. myproject/templates/account/base.html. I recommend extending from the same template you're using for your home template. Make sure this account/base template has the following block, which will be filled in by django-allauth:

{% block content %}
{% endblock %}

Overriding allauth's templates this way (which you may want to do on a per-endpoint basis if you wish to) will only work if you load your own app before allauth in your settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'myapp',
    'allauth',
    'allauth.account',
    ...
like image 1
raphv Avatar answered Nov 20 '22 17:11

raphv