From 07f9e2f0e24b98651108a6399f180e54f12842a4 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 4 Mar 2019 18:44:56 +0100 Subject: [PATCH] Allow signup with threshold. Close #4 --- friends_map/settings.py | 2 ++ map/forms.py | 8 +++++ map/templates/map/base_change.html | 16 +++++---- map/templates/map/change_profile.html | 1 + map/templates/registration/login.html | 1 + map/templates/registration/signup.html | 48 ++++++++++++++++++++++++++ map/urls.py | 1 + map/views.py | 27 ++++++++++++++- 8 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 map/templates/registration/signup.html diff --git a/friends_map/settings.py b/friends_map/settings.py index 156e828..ae58882 100644 --- a/friends_map/settings.py +++ b/friends_map/settings.py @@ -160,4 +160,6 @@ CRISPY_TEMPLATE_PACK = 'bootstrap4' LOGOUT_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = '/' +USER_THRESHOLD = os.getenv('USER_THRESHOLD', 10) + django_heroku.settings(locals(), allowed_hosts=False, databases=DJANGO_ENV == 'prod') diff --git a/map/forms.py b/map/forms.py index b62b4ee..91184da 100644 --- a/map/forms.py +++ b/map/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.contrib.auth.forms import UserCreationForm from map.models import FriendLocation, Friend @@ -35,3 +36,10 @@ class LocationSharingForm(forms.ModelForm): self.request = request self.fields['shares_location_to'].queryset = Friend.objects.exclude(pk=request.user.pk) self.fields['shares_location_to'].label = 'Share location to' + + +class FriendCreationForm(UserCreationForm): + class Meta(UserCreationForm.Meta): + model = Friend + fields = UserCreationForm.Meta.fields + diff --git a/map/templates/map/base_change.html b/map/templates/map/base_change.html index ff5bc51..1680fd3 100644 --- a/map/templates/map/base_change.html +++ b/map/templates/map/base_change.html @@ -4,11 +4,13 @@ {% block content %} {% block notice %} {% endblock %} -
- {% csrf_token %} - {{ form|crispy }} - {% block form-buttons %} - - {% endblock %} -
+ {% block form %} +
+ {% csrf_token %} + {{ form|crispy }} + {% block form-buttons %} + + {% endblock %} +
+ {% endblock %} {% endblock %} diff --git a/map/templates/map/change_profile.html b/map/templates/map/change_profile.html index 0c5ac44..46c399b 100644 --- a/map/templates/map/change_profile.html +++ b/map/templates/map/change_profile.html @@ -26,6 +26,7 @@ {% endblock %} {% block form-buttons %} + Change your password Permanently delete your profile {% endblock %} diff --git a/map/templates/registration/login.html b/map/templates/registration/login.html index a358613..8948718 100644 --- a/map/templates/registration/login.html +++ b/map/templates/registration/login.html @@ -9,5 +9,6 @@ {% csrf_token %} {{ form|crispy }} + I don't have an account {% endblock %} diff --git a/map/templates/registration/signup.html b/map/templates/registration/signup.html new file mode 100644 index 0000000..a37efed --- /dev/null +++ b/map/templates/registration/signup.html @@ -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 %} +
+

Notice

+
+ Registration is currently not allowed. Thanks for your interest, please come back later. +
+
+ {% else %} +
+

Notice

+
+ 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. +
+ 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. +
+
+
+ You can also permanently delete your profile using the button at the bottom of this page. + This will prompt you for confirmation about permanently and + immediately + deleting your profile, meaning that we will not be able to retrieve + your data if you change your mind. +
+
+ {% endif %} +{% endblock %} +{% block form %} + {% if not registration_disallowed %} +
+ {% csrf_token %} + {{ form|crispy }} + {% block form-buttons %} + + {% endblock %} +
+ {% endif %} +{% endblock %} diff --git a/map/urls.py b/map/urls.py index 2bdfd4d..4936013 100644 --- a/map/urls.py +++ b/map/urls.py @@ -8,6 +8,7 @@ urlpatterns = [ path('add-location', views.AddLocationView.as_view(), name='add-location'), path('delete-location', views.DeleteLocationView.as_view(), name='delete-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/delete', views.DeleteProfileView.as_view(), name='delete-profile'), ] diff --git a/map/views.py b/map/views.py index 4e2289d..a57a737 100644 --- a/map/views.py +++ b/map/views.py @@ -1,11 +1,13 @@ +from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy from django.views import generic from map import models -from map.forms import LocationForm, LocationSharingForm +from map.forms import LocationForm, LocationSharingForm, FriendCreationForm from map.mixins import QuickActionsMixin +from map.models import Friend class MapView(LoginRequiredMixin, QuickActionsMixin, generic.DetailView): @@ -111,6 +113,29 @@ class DeleteLocationView(LoginRequiredMixin, generic.DeleteView): 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): model = models.Friend context_object_name = 'friend'