Add User+Authenticate(login,logout,reset password)

Also add view for signup page + custom form for signup
This commit is contained in:
sosokker 2023-09-11 23:38:13 +07:00
parent d6fd968ea4
commit 01ea565859
13 changed files with 163 additions and 6 deletions

View File

@ -126,3 +126,9 @@ STATICFILES_DIRS = [BASE_DIR]
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_REDIRECT_URL = "home_redirect"
LOGOUT_REDIRECT_URL = "home_redirect"
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = BASE_DIR / "sent_emails"

View File

@ -7,4 +7,5 @@ urlpatterns = [
path('', RedirectView.as_view(pattern_name='polls:index'), name='home_redirect'), path('', RedirectView.as_view(pattern_name='polls:index'), name='home_redirect'),
path("polls/", include("polls.urls")), path("polls/", include("polls.urls")),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")),
] ]

27
polls/forms.py Normal file
View File

@ -0,0 +1,27 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
tailwind_class = "w-full border-2 border-gray-300 bg-gray-100 rounded-lg focus:ring focus:border-blue-300 focus:shadow-none"
username = forms.CharField(widget=forms.TextInput(attrs={'class': tailwind_class}),
error_messages={
'unique': 'This username is already in use.',
'invalid': 'Invalid username format.',
'max_length': 'Username should not exceed 150 characters.',
}
)
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class': tailwind_class}),
error_messages={'min_length': 'Password must contain at least 8 characters.',}
)
password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': tailwind_class}),)
class Meta:
model = User
fields = ('username', 'password1', 'password2')
error_messages = {
'password_mismatch': "The two password fields didn't match.",
}

View File

@ -14,6 +14,7 @@ from django.utils import timezone
from django.contrib import admin from django.contrib import admin
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
from django.db.models import Sum from django.db.models import Sum
from django.contrib.auth.models import User
class Question(models.Model): class Question(models.Model):

View File

@ -26,15 +26,22 @@
</button> </button>
</form> </form>
<!--End--> <!--End-->
<button class="flex items-center whitespace-nowrap rounded-full border border-transparent bg-green-500 px-5 py-2 text-sm font-bold text-white transition duration-150 ease-in-out hover:scale-[101%] hover:bg-green-700 focus:bg-green-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-green-900">
New Poll
</button>
</div> </div>
</header> </header>
<a href="" {% if user.is_authenticated %}
class="flex items-center whitespace-nowrap rounded-full border border-transparent bg-neutral-800 px-5 py-2 text-sm font-bold text-white transition duration-150 ease-in-out hover:scale-[101%] hover:bg-neutral-700 focus:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-neutral-900"> <button class="flex items-center whitespace-nowrap rounded-full border border-transparent bg-green-500 px-5 py-2 text-sm font-bold text-white transition duration-150 ease-in-out hover:scale-[101%] hover:bg-green-700 focus:bg-green-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-green-900">
New Poll
</button>
<a href="{% url 'logout' %}"
class="flex items-center whitespace-nowrap rounded-full border border-transparent bg-red-600 px-5 py-2 text-sm font-bold text-white transition duration-150 ease-in-out hover:scale-[101%] hover:bg-red-700 focus:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-neutral-900">
<span>Sign out <span class="hidden sm:inline-block">😭</span></span>
</a>
{% else %}
<a href="{% url 'login' %}"
class="flex items-center whitespace-nowrap rounded-full border border-transparent bg-neutral-800 px-5 py-2 text-sm font-bold text-white transition duration-150 ease-in-out hover:scale-[101%] hover:bg-neutral-700 focus:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-red-900">
<span>Sign in <span class="hidden sm:inline-block">😎</span></span> <span>Sign in <span class="hidden sm:inline-block">😎</span></span>
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sign In Page</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center">
<div class="bg-white p-8 shadow-md rounded-md w-96">
<h2 class="text-3xl font-semibold text-center mb-6">Sign In</h2>
<form method="post">
{% csrf_token %}
<div class="mb-6 flex flex-col">
<p class="block text-gray-700 font-medium mb-2">Username</p>
{{ form.username }}
</div>
<div class="mb-6 flex flex-col">
<p class="block text-gray-700 font-medium mb-2">Password</p>
{{ form.password }}
</div>
<button
type="submit"
class="w-full bg-blue-500 text-white py-2 rounded-md hover:bg-blue-600 focus:ring-2 focus:ring-blue-300 focus:outline-none">
Log In
</button>
</form>
<p class="text-center mt-4 text-gray-600 text-sm">
Don't have an account? <a href="{% url 'polls:signup' %}" class="text-blue-500 hover:underline">Sign up here</a>
</p>
<p class="text-center mt-4 text-gray-600 text-sm">
Forget the Password? <a href="{% url 'password_reset' %}" class="text-blue-500 hover:underline">Reset here</a>
</p>
<a href="{% url 'polls:index' %}" class="mt-4 block text-center text-blue-500 hover:underline">Back to Poll</a>
</div>
</body>
</html>

View File

@ -0,0 +1,2 @@
<h1>Password reset complete</h1>
<p>Your new password has been set. You can log in now on the <a href="{% url 'login' %}">log in page</a>.</p>

View File

@ -0,0 +1,12 @@
{% if validlink %}
<h1>Set a new password!</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Change my password">
</form>
{% else %}
<p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>

View File

@ -0,0 +1,2 @@
<h1>Check your inbox.</h1>
<p>We've emailed you instructions for setting your password. You should receive the email shortly!</p>

View File

@ -0,0 +1,8 @@
<h1>Forgot your password?</h1>
<p>Enter your email address below, and we'll email instructions for setting a new one.</p>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Send me instructions!">
</form>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign Up Page</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100">
<div class="min-h-screen flex items-center justify-center">
<div class="bg-white p-8 shadow-md rounded-md w-96">
<h2 class="text-2xl font-semibold mb-6">Sign Up</h2>
<form method="post">
{% csrf_token %}
<div class="mb-4">
<p class="block text-gray-700 font-medium">Username</p>
{{ form.username }}
</div>
<div class="mb-4">
<p class="block text-gray-700 font-medium">Password</p>
{{ form.password1 }}
<div class="mb-4">
<p class="block text-gray-700 font-medium">Password Confirmation</p>
{{ form.password2 }}
</div>
<button type="submit" class="w-full bg-green-500 text-white py-2 rounded-md hover:bg-green-600 focus:ring-2 focus:ring-green-300 focus:outline-none">Sign Up</button>
<!-- text form -->
<p class="mt-2 text-gray-600 text-sm">Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.</p>
<p class="mt-2 text-gray-600 text-sm">Your password cant be too similar to your other personal information. , must contain at least 8 characters, cant be entirely numeric.</p>
</form>
<div class="mt-2 text-gray-600 text-sm">
{% if form.errors %}
{% for field in form %}
{% if field.errors %}
{% for error in field.errors %}
<p class="text-red-500">{{ error }}</p>
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
</div>
<p class="mt-4 text-gray-600 text-sm">Already have an account? <a href="{% url 'login' %}" class="text-blue-500 hover:underline">Sign in here</a></p>
<a href="{% url 'polls:index' %}" class="mt-4 block text-center text-blue-500 hover:underline">Back to Poll</a>
</div>
</div>
</body>
</html>

View File

@ -8,4 +8,5 @@ urlpatterns = [
path("<int:pk>/", views.DetailView.as_view(), name="detail"), path("<int:pk>/", views.DetailView.as_view(), name="detail"),
path("<int:pk>/results/", views.ResultsView.as_view(), name="results"), path("<int:pk>/results/", views.ResultsView.as_view(), name="results"),
path("<int:question_id>/vote/", views.vote, name="vote"), path("<int:question_id>/vote/", views.vote, name="vote"),
path("signup/", views.SignUpView.as_view(), name="signup"),
] ]

View File

@ -3,8 +3,9 @@ from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.views import generic from django.views import generic
from django.utils import timezone from django.utils import timezone
from django.views.generic import TemplateView from django.urls import reverse_lazy
from .forms import SignUpForm
from .models import Choice, Question from .models import Choice, Question
@ -66,6 +67,12 @@ class ResultsView(generic.DetailView):
return render(self.request, self.template_name, context) return render(self.request, self.template_name, context)
class SignUpView(generic.CreateView):
form_class = SignUpForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
def vote(request, question_id): def vote(request, question_id):
""" """
A function that update the database. Add vote count to choice that user vote A function that update the database. Add vote count to choice that user vote