STAY INFORMED
following content serves as a personal note and may lack complete accuracy or
certainty.
Minimal-Mistakes instruction
Useful vscode Shortcut Keys
Unix Commands
npm Commands
Vim Commands
Git Note
Useful Figma Shortcut Keys
Share Hub Project_1
Setup
mkdir share-hub
cd share-hub
pyenv virtualenv 3.7.13 django_shareHub_env
pip3 install django==2.2
pyenv local django_shareHub_env
django-admin startproject shareHub_project
cd shareHub_project
python manage.py startapp shareHub
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shareHub',
]
Create User Model
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
Additionally, for an user model, you need to add ‘AUTH_USER_MODEL = “[app-name].User’” to settings.py at very bottom.
# settings.py
AUTH_USER_MODEL = 'shareHub.User'
Register Model to Admin Page
# admin.py
from django.contrib import admin
from .models import User
from django.contrib.auth.admin import UserAdmin
admin.site.register(User, UserAdmin)
UserAdmin includes all necessary fields and functionalities, like handling permissions and user information.
Create Super User
python manage.py createsuperuser
# type your info
Django-allauth
There are several things to install for user authentication.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shareHub',
# need to install
'allauth',
'allauth.account',
'allauth.socialaccount',
]
.
.
.
AUTHENTICATION_BACKENDS = [
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',
# `allauth` specific authentication methods, such as login by email
'allauth.account.auth_backends.AuthenticationBackend',
]
# Email settings
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
and add url patterns.
# urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("allauth.urls")),
]
Now login page is added. If you go to localhost:8000/login,
and migrate it since model has been changed.
python manage.py makemigrations
python manage.py migrate
Login / Logout
Setup
First, add path for shareHub app.
# project/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shareHub.urls')),
path('', include("allauth.urls")),
]
# shareHub/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
# views.py
from django.shortcuts import render
def index(request):
return render(request, 'shareHub/index.html')
This redirects to index page from login page after user login.
# settings.py
# set index page before user login
ACCOUNT_SIGNUP_REDIRECT_URL = 'index'
LOGIN_REDIRECT_URL = 'index'
And there are some several thing need to set for handling session, signup, etc.
ACCOUNT_LOGOUT_ON_GET = True # makes logout without asking
ACCOUNT_AUTHENTICATION_METHOD = 'email' # makes user can login with email
ACCOUNT_EMAIL_REQUIRED = True # email is required when signup
ACCOUNT_USERNAME_REQUIRED = False # you won't see username input when signup
# ACCOUNT_SESSION_REMEMBER = True # Computer will remember user without checking 'remember me' checkbox
SESSION_COOKIE_AGE = 3600 # set cookie valid time to an hour (default is 2 weeks)
ACCOUNT_PASSWORD_INPUT_RENDER_VALUE = True # makes the password field show the entered password
more info about allauth setting
Session
When user logout manually, session is automatically deleted but when cookie is expired and user was logged out, session is not deleted. You need to delete it manually, or automatize it. Otherwise, lots of memory will be stacked.
python manage.py clearsessions
Render Page Depending On Login/Logout
is_authenticated return true / false depending user is logged in / out. And the url is from allauth.
<navbar>
{% if user.is_authenticated %}
<a href={% url 'account_logout' %}>logout</a>
{% else %}
<a href={% url 'account_login' %}>sign in</a>
<a href={% url 'account_signup' %}>sign up</a>
{% endif %}
</navbar>
<h1>homepage</h1>
{% if user.is_authenticated %}
<p>Hello {{user}}</p>
<p>Email: {{user.email}}</p>
{% else %}
<p>need to login</p>
{% endif %}
Signup Form
There is default signup form, and you can add what you want from user’s info like nickname and so on.
# forms.py
from django import forms
from .models import User
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ['nickname']
def signup(self, request, user):
user.nickname = self.cleaned_data['nickname']
user.save()
# settings.py
ACCOUNT_SIGNUP_FORM_CLASS = 'shareHub.forms.SignupForm'
And add nickname field to models.py as well.
# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
nickname = models.CharField(
max_length=15,
unique=True,
null=True,
error_messages={"unique": "This nickname already exists."})
def __str__(self):
return self.email
Password validator
There is default setting for password validator,
# setting.py
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
But you can create your own validator.
AUTH_PASSWORD_VALIDATORS = [
"NAME": "shareHub.validators.CustomPasswordValidator",
]
# validators.py
import string
from django.core.exceptions import ValidationError
def contains_special_character(value):
for char in value:
if char in string.punctuation: # check punctuation is included
return True
return False
def contains_uppercase_letter(value):
for char in value:
if char.isupper():
return True
return False
def contains_lowercase_letter(value):
for char in value:
if char.islower():
return True
return False
def contains_number(value):
for char in value:
if char.isdigit():
return True
return False
class CustomPasswordValidator:
def validate(self, password, user=None):
if (
len(password) < 8 or
not contains_uppercase_letter(password) or
not contains_lowercase_letter(password) or
not contains_number(password)
):
raise ValidationError("Your password must contain at least 8 characters.")
def get_help_text(self):
return "Your password must contain at least 8 characters."
def validate_no_special_characters(value):
if contains_special_character(value):
raise ValidationError("Cannot be included punctuations.")