Merge branch 'no_ip_whitelist' into 'master'
Rework account forms See merge request bde/photo21!2
This commit is contained in:
commit
e2c826ec1d
13 changed files with 111 additions and 67 deletions
|
|
@ -1,13 +1,31 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.forms import UserCreationForm
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class RegistrationForm(UserCreationForm):
|
class RegistrationForm(UserCreationForm):
|
||||||
email = forms.EmailField(label="Email", widget=forms.TextInput(), required=True)
|
email = forms.EmailField(
|
||||||
first_name = forms.CharField(label="Prénom", widget=forms.TextInput(), required=True)
|
label=_("Email address"),
|
||||||
last_name = forms.CharField(label="Nom", widget=forms.TextInput(), required=True)
|
widget=forms.TextInput(),
|
||||||
|
required=True,
|
||||||
|
help_text=_(
|
||||||
|
"Please enter a valid email address ending with `@crans.org` or "
|
||||||
|
"`@ens-paris-saclay.fr`."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean_email(self):
|
||||||
|
"""
|
||||||
|
Check that the email address ends with a trusted domain.
|
||||||
|
"""
|
||||||
|
email = self.cleaned_data.get("email")
|
||||||
|
if not email.endswith("@crans.org") and not email.endswith("@ens-paris-saclay.fr"):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("Must end with `@crans.org` or `@ens-paris-saclay.fr`.")
|
||||||
|
)
|
||||||
|
return email
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ["username", "password1", "password2", "email", "first_name", "last_name"]
|
fields = ["username", "password1", "password2", "email"]
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,20 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
{% comment %}
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
{% endcomment %}
|
||||||
|
{% load i18n crispy_forms_tags %}
|
||||||
|
{% block title %}{% trans "Sign up" %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Création d'utilisateur</h1>
|
<div class="card bg-light">
|
||||||
<form action="" method="post">{% csrf_token %}
|
<h3 class="card-header text-center">
|
||||||
{{ form.as_p }}
|
{% trans "Sign up" %}
|
||||||
<br>
|
</h3>
|
||||||
<input type="submit" value="Envoyer">
|
<div class="card-body">
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<input type="submit" value="Envoyer" class="btn btn-primary mt-4">
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
@ -2,5 +2,5 @@ from django.urls import path
|
||||||
|
|
||||||
from .views import signup
|
from .views import signup
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', signup, name='registration'),
|
path('registration/', signup, name='registration'),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-23 08:18+0000\n"
|
"POT-Creation-Date: 2021-10-08 11:03+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
@ -18,19 +18,41 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
#: photo21/settings.py:128
|
#: accounts/forms.py:9
|
||||||
|
msgid "Email address"
|
||||||
|
msgstr "Adresse email"
|
||||||
|
|
||||||
|
#: accounts/forms.py:13
|
||||||
|
msgid ""
|
||||||
|
"Please enter a valid email address ending with `@crans.org` or `@ens-paris-"
|
||||||
|
"saclay.fr`."
|
||||||
|
msgstr ""
|
||||||
|
"Veuillez entrer une adresse email valide finissant par `@crans.org` ou `@ens-"
|
||||||
|
"paris-saclay.fr`."
|
||||||
|
|
||||||
|
#: accounts/forms.py:25
|
||||||
|
msgid "Must end with `@crans.org` or `@ens-paris-saclay.fr`."
|
||||||
|
msgstr "Doit finir par `@crans.org` ou `@ens-paris-saclay.fr`."
|
||||||
|
|
||||||
|
#: accounts/templates/accounts/registration.html:6
|
||||||
|
#: accounts/templates/accounts/registration.html:11
|
||||||
|
#: photo21/templates/base.html:70
|
||||||
|
msgid "Sign up"
|
||||||
|
msgstr "Inscription"
|
||||||
|
|
||||||
|
#: photo21/settings.py:132
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:129
|
#: photo21/settings.py:133
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:130
|
#: photo21/settings.py:134
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:131
|
#: photo21/settings.py:135
|
||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -90,13 +112,13 @@ msgstr "Galeries"
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/base.html:47
|
#: photo21/templates/base.html:51
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/base.html:53 photo21/templates/registration/login.html:6
|
#: photo21/templates/base.html:61 photo21/templates/registration/login.html:6
|
||||||
#: photo21/templates/registration/login.html:15
|
#: photo21/templates/registration/login.html:11
|
||||||
#: photo21/templates/registration/login.html:37
|
#: photo21/templates/registration/login.html:33
|
||||||
#: photo21/templates/registration/password_reset_complete.html:15
|
#: photo21/templates/registration/password_reset_complete.html:15
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -113,24 +135,24 @@ msgstr ""
|
||||||
msgid "Log in again"
|
msgid "Log in again"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/registration/login.html:20
|
#: photo21/templates/registration/login.html:16
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"You are authenticated as %(username)s, but are not authorized to access this "
|
"You are authenticated as %(username)s, but are not authorized to access this "
|
||||||
"page. Would you like to login to a different account?"
|
"page. Would you like to login to a different account?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/registration/login.html:29
|
#: photo21/templates/registration/login.html:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"You must be logged with a staff account with the higher mask to access "
|
"You must be logged with a staff account with the higher mask to access "
|
||||||
"Django Admin."
|
"Django Admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/registration/login.html:39
|
#: photo21/templates/registration/login.html:35
|
||||||
msgid "Forgotten your password or username?"
|
msgid "Forgotten your password or username?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/registration/login.html:43
|
#: photo21/templates/registration/login.html:39
|
||||||
msgid "If any problem, please contact the server owners at"
|
msgid "If any problem, please contact the server owners at"
|
||||||
msgstr "En cas de problème, contactez les administrateurs à"
|
msgstr "En cas de problème, contactez les administrateurs à"
|
||||||
|
|
||||||
|
|
@ -220,7 +242,7 @@ msgstr ""
|
||||||
msgid "Published"
|
msgid "Published"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_detail.html:34
|
#: photologue_custom/templates/photologue/gallery_detail.html:41
|
||||||
msgid "Download all gallery"
|
msgid "Download all gallery"
|
||||||
msgstr "Télécharger toute la galerie"
|
msgstr "Télécharger toute la galerie"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
import ipaddress
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,30 +19,9 @@ class LoginRequiredMiddleware:
|
||||||
If user is not authenticated and external, redirect to login view
|
If user is not authenticated and external, redirect to login view
|
||||||
before calling the view.
|
before calling the view.
|
||||||
"""
|
"""
|
||||||
if not request.user.is_authenticated and not self.check_ip(request):
|
if not request.user.is_authenticated:
|
||||||
if not self.whitelist_re.match(request.path_info):
|
if not self.whitelist_re.match(request.path_info):
|
||||||
return HttpResponseRedirect(settings.LOGIN_URL)
|
return HttpResponseRedirect(settings.LOGIN_URL)
|
||||||
|
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def check_ip(self, request):
|
|
||||||
"""
|
|
||||||
Return true if IP is in authorized range
|
|
||||||
"""
|
|
||||||
# Get IP address
|
|
||||||
if 'HTTP_X_REAL_IP' in request.META:
|
|
||||||
ip = request.META.get('HTTP_X_REAL_IP')
|
|
||||||
elif 'HTTP_X_FORWARDED_FOR' in request.META:
|
|
||||||
ip = request.META.get('HTTP_X_FORWARDED_FOR').split(', ')[0]
|
|
||||||
else:
|
|
||||||
ip = request.META.get('REMOTE_ADDR')
|
|
||||||
ip = ipaddress.ip_address(ip)
|
|
||||||
|
|
||||||
# Check against ranges
|
|
||||||
if hasattr(settings, 'LOGIN_EXEMPT_IP_RANGE'):
|
|
||||||
for ip_range in settings.LOGIN_EXEMPT_IP_RANGE:
|
|
||||||
net = ipaddress.ip_network(ip_range)
|
|
||||||
if ip in net:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'crispy_forms',
|
||||||
'photologue_custom',
|
'photologue_custom',
|
||||||
'photologue',
|
'photologue',
|
||||||
'accounts',
|
'accounts',
|
||||||
|
|
@ -163,8 +164,8 @@ SESSION_COOKIE_AGE = 60 * 60 * 3
|
||||||
# Use only one Django Sites
|
# Use only one Django Sites
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
|
||||||
|
# use Bootstrap forms
|
||||||
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
# Photologue
|
# Photologue
|
||||||
PHOTOLOGUE_GALLERY_SAMPLE_SIZE = 1
|
PHOTOLOGUE_GALLERY_SAMPLE_SIZE = 1
|
||||||
|
|
||||||
# IP range whitelist
|
|
||||||
LOGIN_EXEMPT_IP_RANGE = ["185.230.76.0/22", "2a0c:700::/32"]
|
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,32 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{% url 'logout' %}">
|
<a class="nav-link" href="{% url 'logout' %}">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z"/>
|
||||||
|
<path fill-rule="evenodd" d="M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
|
||||||
|
</svg>
|
||||||
{% trans "Log out" %}
|
{% trans "Log out" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{% url 'login' %}">
|
<a class="nav-link" href="{% url 'login' %}">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-right" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M6 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 0-1 0v2A1.5 1.5 0 0 0 6.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-8A1.5 1.5 0 0 0 5 3.5v2a.5.5 0 0 0 1 0v-2z"/>
|
||||||
|
<path fill-rule="evenodd" d="M11.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H1.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
|
||||||
|
</svg>
|
||||||
{% trans "Log in" %}
|
{% trans "Log in" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'registration' %}">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-plus" viewBox="0 0 16 16">
|
||||||
|
<path d="M6 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H1s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/>
|
||||||
|
<path fill-rule="evenodd" d="M13.5 5a.5.5 0 0 1 .5.5V7h1.5a.5.5 0 0 1 0 1H14v1.5a.5.5 0 0 1-1 0V8h-1.5a.5.5 0 0 1 0-1H13V5.5a.5.5 0 0 1 .5-.5z"/>
|
||||||
|
</svg>
|
||||||
|
{% trans "Sign up" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,9 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n static %}
|
{% load i18n crispy_forms_tags %}
|
||||||
{% block title %}{% trans "Log in" %}{% endblock %}
|
{% block title %}{% trans "Log in" %}{% endblock %}
|
||||||
|
|
||||||
{% block extracss %}
|
|
||||||
<link rel="stylesheet" href="{% static "registration/css/login.css" %}">
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card bg-light mx-auto" style="max-width: 35rem;">
|
<div class="card bg-light mx-auto" style="max-width: 35rem;">
|
||||||
<h3 class="card-header text-center">
|
<h3 class="card-header text-center">
|
||||||
|
|
@ -33,8 +29,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
|
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
|
||||||
{{ form }}
|
{{ form|crispy }}
|
||||||
<input type="submit" value="{% trans 'Log in' %}" class="btn btn-primary btn-block btn-lg">
|
<input type="submit" value="{% trans 'Log in' %}" class="btn btn-primary btn-lg mt-2">
|
||||||
<a href="{% url 'password_reset' %}"
|
<a href="{% url 'password_reset' %}"
|
||||||
class="badge bg-light text-dark">{% trans 'Forgotten your password or username?' %}</a>
|
class="badge bg-light text-dark">{% trans 'Forgotten your password or username?' %}</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n crispy_forms_tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card bg-light">
|
<div class="card bg-light">
|
||||||
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">{% csrf_token %}
|
<form method="post">{% csrf_token %}
|
||||||
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
|
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||||
{{ form }}
|
{{ form|crispy }}
|
||||||
<input class="btn btn-primary" type="submit" value="{% trans 'Change my password' %}">
|
<input class="btn btn-primary" type="submit" value="{% trans 'Change my password' %}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n crispy_forms_tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card bg-light">
|
<div class="card bg-light">
|
||||||
|
|
@ -13,8 +13,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% if validlink %}
|
{% if validlink %}
|
||||||
<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
|
<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||||
<form method="post">{% csrf_token %}
|
<form method="post">{% csrf_token %}
|
||||||
{{ form }}
|
{{ form|crispy }}
|
||||||
<input class="btn btn-primary" type="submit" value="{% trans 'Change my password' %}">
|
<input class="btn btn-primary mt-4" type="submit" value="{% trans 'Change my password' %}">
|
||||||
</form>
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% load i18n %}
|
{% load i18n crispy_forms_tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="card bg-light">
|
<div class="card bg-light">
|
||||||
|
|
@ -14,8 +14,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form|crispy }}
|
||||||
<input class="btn btn-primary" type="submit" value="{% trans 'Reset my password' %}">
|
<input class="btn btn-primary mt-4" type="submit" value="{% trans 'Reset my password' %}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ urlpatterns = [
|
||||||
path('photologue/', include('photologue_custom.urls')),
|
path('photologue/', include('photologue_custom.urls')),
|
||||||
path('photologue/', include('photologue.urls', namespace='photologue')),
|
path('photologue/', include('photologue.urls', namespace='photologue')),
|
||||||
path('accounts/', include('django.contrib.auth.urls')),
|
path('accounts/', include('django.contrib.auth.urls')),
|
||||||
|
path('accounts/', include('accounts.urls')),
|
||||||
path('i18n/', include('django.conf.urls.i18n')),
|
path('i18n/', include('django.conf.urls.i18n')),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
||||||
path('accounts/registration/', include('accounts.urls'))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
Django~=2.2.20
|
Django~=2.2.20
|
||||||
django-photologue~=3.13
|
django-photologue~=3.13
|
||||||
django-taggit~=1.5.1
|
django-taggit~=1.5.1
|
||||||
|
django-crispy-forms~=1.7
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue