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

5 minute read

Setup

mkdir e-commerce-project
cd e-commerce-project
pyenv virtualenv 3.7.13 django_ecommerce_env
pip3 install django==2.2
pyenv local django_ecommerce_env
django-admin startproject ecommerce_project
cd ecommerce_project
python manage.py startapp ecommerce
# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'ecommerce',
]

Pages

we need pages for

  • index(homepage)
  • sign in
  • sign up
  • user profile
  • item list
  • item detail

Since sign in, sign up pages already exist, I will just change urls.py in project directory and create the rest.

The file structure should be

ecommerce_project/
    ecommerce/
        static/
            ecommerce/
                favicon/
                    favicon.svg
                assets/
                    ...
                styles/
                    style.css
                    ...
        templates/
            ecommerce/
                index.html
                ...
            ecommerce_base/
                base.html
                ...

I simply made base.html

{% load static %}

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <link
      rel="shortcut icon"
      type="image/png"
      href="{% static 'ecommerce/favicon/favicon.svg' %}"
    />

    <title>{% block title %}Coplate{% endblock title %}</title>
  </head>
  <body>
    {% block header %}{% endblock header %} {% block content %}{% endblock
    content %} {% block footer %}{% endblock footer %}
  </body>
</html>

and index.html

{% extends "ecommerce_base/base.html" %} {% block content %}
<h1>hi</h1>
{% endblock content %}

To render the page,

# urls.py in project dir
from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    # admin
    path('admin/', admin.site.urls),

    # ecommerce
    path('', include("ecommerce.urls")),

    # allauth
    path('', include("allauth.urls")), # for sign in, sign up, etc
]

# urls.py in ecommerce
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, "ecommerce/index.html")

Now I see index, login pages.

des1

des2

Create User

Create User Model

For user model, I will use AbstractUser module which offers basic user model schema, so User model inherits AbstractUser and you need to add ‘AUTH_USER_MODEL = “[app-name].User”` to settings.py at very bottom.

# 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) # additional schema

    def __str__(self):
        return self.nickname

and register User 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

To check User model is successfully registered, create superuser.

python manage.py createsuperuser
# type your info

and go to /admin and check it.

des3

allauth

Setup

Quick start

django-allauth is a Django application that provides comprehensive user authentication, registration, and account management functionalities. It simplifies the integration of user authentication and social account logins into your Django project.

pip install django-allauth
# settings.py
INSTALLED_APPS = [
    ...
    'ecommerce',

    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
]
SITE_ID = 1
...
MIDDLEWARE = [
    ...
    'allauth.account.middleware.AccountMiddleware',
    ...
]

...
# Auth settings

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 migrate it

python manage.py migrate

Handling sign up

When user sign up successfully, it redirect to account/profile, which I haven’t made the page, so it will give 404 error. I don’t need to page, and just add some code to settings.py.

# settings.py
...
# redirect to index page when signup successfully
ACCOUNT_SIGNUP_REDIRECT_URL = "index"
LOGIN_REDIRECT_URL = "index"

I will add some more.

ACCOUNT_LOGOUT_ON_GET = True  # not redirect to logout page
ACCOUNT_AUTHENTICATION_METHOD = "email" # require email when login instead of username
ACCOUNT_EMAIL_REQUIRED = True # Email is required when sign up
ACCOUNT_USERNAME_REQUIRED = False # username field is gone on sign up form
ACCOUNT_SESSION_REMEMBER = True # browser remember user depending on the line below
SESSION_COOKIE_AGE = 3600 # default is 2 weeks

Also, since I added nickname field in user model, I will make signup form.

# 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()

and add this line in settings.py to apply signup form.

# settings.py
ACCOUNT_SIGNUP_FORM_CLASS = "ecommerce.forms.SignupForm" # use SignupForm in forms.py instead

Account email verification

# settings.py
ACCOUNT_EMAIL_VERIFICATION = "mandatory" # user cannot login until verify email
ACCOUNT_CONFIRM_EMAIL_ON_GET = True # redirect to login page

# redirect to account_email_confirmation_done page
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = "account_email_confirmation_done"
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = "account_email_confirmation_done"

and add a path for confirmation page in urls.py in project dir.

from django.views.generic import TemplateView

urlpatterns = [
    # admin
    path('admin/', admin.site.urls),

    # ecommerce
    path('', include("ecommerce.urls")),

    # allauth
    path(
        "email-confirmation-done/",
        TemplateView.as_view(template_name="ecommerce/email.confirmation_done.html"),
        name="account_email_confirmation_done"),
    path('', include("allauth.urls")), # for sign in, sign up, etc
]

Now I need to create a template for confirmation.

Email Confirmed.

<a href="{% url 'account_login'%}">go to login</a>

When user signup, user will get a link and if user click the link, it redirects to this page and email is confirmed.

des4

des5

Handling password

  • when change password before sign in(forgot password)

Just simply add this line in settings.py

# settings.py
PASSWORD_RESET_TIMEOUT = 600 # Sets the number of seconds a password reset link remains valid.
  • when change password after sign in I added a link to change password in index.html
<a href="{% url 'account_change_password' %}">change password</a>

and create view class for password change view.

# views. py
from django.urls import reverse
from allauth.account.views import PasswordChangeView

class CustomPasswordChangeView(PasswordChangeView):
    def get_success_url(self):
        return reverse("index")

and add path for this.

# project/urls.py
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from ecommerce.views import CustomPasswordChangeView

urlpatterns = [
    ...
    # allauth
    path(
        "email-confirmation-done/",
        TemplateView.as_view(template_name="ecommerce/email.confirmation_done.html"),
        name="account_email_confirmation_done"),
    path('password/change/',
        CustomPasswordChangeView.as_view(),
        name="account_password_change",
        ),
    path('', include("allauth.urls")), # for sign in, sign up, etc
]

Clear session

This is clear session command. Need to make auto-system to execute this.

python manage.py clearsessions
Learned New

Since I created user(including superuser) before I make a User model which has nickname field, the user accounts don’t have a nickname. To fix this issue, make nickname field accepts null,

# 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)

    def __str__(self):
        return self.email

and add this line so that admin page will display nickname field.

# admin.py
UserAdmin.fieldsets += (("Custom fields", {"fields": ("nickname", )}), )

des6

Now you can define nickname.