Allow signup with threshold. Close #4
This commit is contained in:
parent
b9355fda7d
commit
07f9e2f0e2
8 changed files with 96 additions and 8 deletions
|
@ -160,4 +160,6 @@ CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
LOGOUT_REDIRECT_URL = '/'
|
LOGOUT_REDIRECT_URL = '/'
|
||||||
LOGIN_REDIRECT_URL = '/'
|
LOGIN_REDIRECT_URL = '/'
|
||||||
|
|
||||||
|
USER_THRESHOLD = os.getenv('USER_THRESHOLD', 10)
|
||||||
|
|
||||||
django_heroku.settings(locals(), allowed_hosts=False, databases=DJANGO_ENV == 'prod')
|
django_heroku.settings(locals(), allowed_hosts=False, databases=DJANGO_ENV == 'prod')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
|
||||||
from map.models import FriendLocation, Friend
|
from map.models import FriendLocation, Friend
|
||||||
|
|
||||||
|
@ -35,3 +36,10 @@ class LocationSharingForm(forms.ModelForm):
|
||||||
self.request = request
|
self.request = request
|
||||||
self.fields['shares_location_to'].queryset = Friend.objects.exclude(pk=request.user.pk)
|
self.fields['shares_location_to'].queryset = Friend.objects.exclude(pk=request.user.pk)
|
||||||
self.fields['shares_location_to'].label = 'Share location to'
|
self.fields['shares_location_to'].label = 'Share location to'
|
||||||
|
|
||||||
|
|
||||||
|
class FriendCreationForm(UserCreationForm):
|
||||||
|
class Meta(UserCreationForm.Meta):
|
||||||
|
model = Friend
|
||||||
|
fields = UserCreationForm.Meta.fields
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% block notice %}
|
{% block notice %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block form %}
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
|
@ -12,3 +13,4 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block form-buttons %}
|
{% block form-buttons %}
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
<a href="{% url 'password_change' %}" class="btn btn-secondary">Change your password</a>
|
<a href="{% url 'password_change' %}" class="btn btn-secondary">Change your password</a>
|
||||||
<a href="{% url 'delete-profile' %}" class="btn btn-warning">Permanently delete your profile</a>
|
<a href="{% url 'delete-profile' %}" class="btn btn-warning">Permanently delete your profile</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,5 +9,6 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
{{ form|crispy }}
|
||||||
<button type="submit" class="btn btn-primary">Login</button>
|
<button type="submit" class="btn btn-primary">Login</button>
|
||||||
|
<a href="{% url 'signup' %}" class="btn btn-secondary">I don't have an account</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
48
map/templates/registration/signup.html
Normal file
48
map/templates/registration/signup.html
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{% extends 'map/change_profile.html' %}
|
||||||
|
{% load crispy_forms_filters %}
|
||||||
|
|
||||||
|
{% block title %}Create your profile{% endblock %}
|
||||||
|
{% block h1 %}Create your profile{% endblock %}
|
||||||
|
|
||||||
|
{% block notice %}
|
||||||
|
{% if registration_disallowed %}
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<h4 class="alert-heading">Notice</h4>
|
||||||
|
<div>
|
||||||
|
Registration is currently not allowed. Thanks for your interest, please come back later.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<h4 class="alert-heading">Notice</h4>
|
||||||
|
<div>
|
||||||
|
The only required field is your username, which you can customize nearly freely.
|
||||||
|
If you choose to add your first and last name, they will be displayed on the map and on the right of the
|
||||||
|
navbar, at the top. If you don't, your username will be displayed instead.
|
||||||
|
<br>
|
||||||
|
Your email address will only ever be used to communicate account-related information. It will never be
|
||||||
|
sold
|
||||||
|
or used to spam you. You can choose not to communicate your email address.
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div>
|
||||||
|
You can also permanently delete your profile using the button at the bottom of this page.
|
||||||
|
This will prompt you for confirmation about <strong>permanently</strong> and
|
||||||
|
<strong>immediately</strong>
|
||||||
|
deleting your profile, meaning that we will not be able to retrieve
|
||||||
|
your data if you change your mind.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block form %}
|
||||||
|
{% if not registration_disallowed %}
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
{% block form-buttons %}
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
{% endblock %}
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
|
@ -8,6 +8,7 @@ urlpatterns = [
|
||||||
path('add-location', views.AddLocationView.as_view(), name='add-location'),
|
path('add-location', views.AddLocationView.as_view(), name='add-location'),
|
||||||
path('delete-location', views.DeleteLocationView.as_view(), name='delete-location'),
|
path('delete-location', views.DeleteLocationView.as_view(), name='delete-location'),
|
||||||
path('share-location', views.LocationSharingView.as_view(), name='share-location'),
|
path('share-location', views.LocationSharingView.as_view(), name='share-location'),
|
||||||
|
path('accounts/signup', views.SignupView.as_view(), name='signup'),
|
||||||
path('accounts/profile', views.UpdateProfileView.as_view(), name='change-profile'),
|
path('accounts/profile', views.UpdateProfileView.as_view(), name='change-profile'),
|
||||||
path('accounts/profile/delete', views.DeleteProfileView.as_view(), name='delete-profile'),
|
path('accounts/profile/delete', views.DeleteProfileView.as_view(), name='delete-profile'),
|
||||||
]
|
]
|
||||||
|
|
27
map/views.py
27
map/views.py
|
@ -1,11 +1,13 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from map import models
|
from map import models
|
||||||
from map.forms import LocationForm, LocationSharingForm
|
from map.forms import LocationForm, LocationSharingForm, FriendCreationForm
|
||||||
from map.mixins import QuickActionsMixin
|
from map.mixins import QuickActionsMixin
|
||||||
|
from map.models import Friend
|
||||||
|
|
||||||
|
|
||||||
class MapView(LoginRequiredMixin, QuickActionsMixin, generic.DetailView):
|
class MapView(LoginRequiredMixin, QuickActionsMixin, generic.DetailView):
|
||||||
|
@ -111,6 +113,29 @@ class DeleteLocationView(LoginRequiredMixin, generic.DeleteView):
|
||||||
return super().get_success_url()
|
return super().get_success_url()
|
||||||
|
|
||||||
|
|
||||||
|
class SignupView(generic.CreateView):
|
||||||
|
model = models.Friend
|
||||||
|
template_name = 'registration/signup.html'
|
||||||
|
success_url = reverse_lazy('login')
|
||||||
|
form_class = FriendCreationForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['registration_disallowed'] = Friend.objects.count() >= settings.USER_THRESHOLD
|
||||||
|
return context
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
if Friend.objects.count() >= settings.USER_THRESHOLD:
|
||||||
|
raise Exception('No more users allowed')
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
self.object.is_active = False
|
||||||
|
self.object.save()
|
||||||
|
messages.success(self.request, 'Your profile has been successfully created, wait for approval.')
|
||||||
|
return super().get_success_url()
|
||||||
|
|
||||||
|
|
||||||
class UpdateProfileView(LoginRequiredMixin, QuickActionsMixin, generic.UpdateView):
|
class UpdateProfileView(LoginRequiredMixin, QuickActionsMixin, generic.UpdateView):
|
||||||
model = models.Friend
|
model = models.Friend
|
||||||
context_object_name = 'friend'
|
context_object_name = 'friend'
|
||||||
|
|
Loading…
Reference in a new issue