Realworld: "The mother of all demo apps" — Exemplary back-end Medium.com clone (called Conduit) in Python, built with Django + DRF + MySQL + MySQLClient + SimpleJWT.
$ git clone https://github.com/yoonge/conduit-drf.git
$ cd conduit-django-ssr
# Activate the virtual environment
$ source ./.venv/bin/activate # MacOS
$ ./.venv/Scripts/activate # Windows
$ pdm install
$ pdm start
# open anthoer terminal
$ source ./.venv/bin/activate
$ pdm makemigrations
$ pdm migrate
$ pdm createsuperuser
And then, open your browser and visit http://localhost:8000/api/
Conduit DRF is MIT-licensed.
$ pip install pdm
$ mkdir conduit-drf && cd conduit-drf
$ pdm init django
# Activate the virtual environment
$ source ./.venv/bin/activate # MacOS
$ ./.venv/Scripts/activate # Windows
$ py manage.py startapp api
$ pdm add djangorestframework, djangorestframework-simplejwt, mysqlclient
# Application definition
INSTALLED_APPS = [
# "django.contrib.admin",
# "django.contrib.auth",
# "django.contrib.contenttypes",
# "django.contrib.sessions",
# "django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"rest_framework_simplejwt",
"api",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
# "django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
# "django.middleware.csrf.CsrfViewMiddleware",
# "django.contrib.auth.middleware.AuthenticationMiddleware",
# "django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "conduit_drf.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
# "django.contrib.auth.context_processors.auth",
# "django.contrib.messages.context_processors.messages",
],
},
},
]
# ...
# LANGUAGE_CODE = "zh-hans"
TIME_ZONE = "Asia/Shanghai"
# ...
AUTH_USER_MODEL = "api.User"
LOGIN_REDIRECT_URL = "/api/"
LOGOUT_REDIRECT_URL = "/api/"
# APPEND_SLASH = False
# SILENCED_SYSTEM_CHECKS = ['urls.W002']
NON_FIELD_ERRORS_KEY = "custom_errors"
# REST framework
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
"rest_framework.authentication.SessionAuthentication",
),
"DEFAULT_PAGINATION_CLASS": "api.utils.pagination.CustomPagination",
"DEFAULT_PERMISSION_CLASSES": (
"rest_framework.permissions.IsAuthenticated",
),
"UNAUTHENTICATED_USER": None,
}
# DRF Simple JWT
SIMPLE_JWT = {
"USER_ID_FIELD": "_id",
"TOKEN_OBTAIN_SERIALIZER": "api.serializers.MyTokenObtainPairSerializer",
}