commit 245cc45e5e476a9c1cf9d6c44fedd4e3bc1197a9
Author: srfsh <srfsh@sonu.ch>
Date: Mon, 28 Jun 2021 13:31:29 +0300
Init
Diffstat:
33 files changed, 550 insertions(+), 0 deletions(-)
diff --git a/.editorconfig b/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = tab
+indent_size = tab
+tab_width = 8
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.ex/dev.py b/.ex/dev.py
@@ -0,0 +1,13 @@
+from .common import BASE_DIR
+
+DEBUG = True
+PORT = "8000"
+INTERNAL_IPS = ["localhost", "127.0.0.1", "::1"]
+SECRET_KEY = "secret_me_harder"
+ALLOWED_HOSTS = ["localhost", "127.0.0.1", "::1"]
+DATABASES = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": BASE_DIR / "db.sqlite3",
+ },
+}
diff --git a/.ex/prod.py b/.ex/prod.py
@@ -0,0 +1,12 @@
+from .common import BASE_DIR
+
+DEBUG = False
+INTERNAL_IPS = ["localhost", "127.0.0.1", "::1"]
+SECRET_KEY = "openssl rand -hex 16"
+ALLOWED_HOSTS = ["localhost", "127.0.0.1", "::1"]
+DATABASES = {
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": BASE_DIR / "db.sqlite3",
+ },
+}
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,12 @@
+# exclude the custom settings from the project
+/base/settings/dev.py
+/base/settings/prod.py
+
+# STATIC_ROOT and MEDIA_ROOT
+/asset/
+
+/.vscode/
+/db.sqlite3
+
+*.pyc
+__pycache__/
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2021 Senior Fish <srfsh@sonu.ch>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/Makefile b/Makefile
@@ -0,0 +1,23 @@
+all: start-django
+
+start-django:
+ @poetry run ./manage.py runserver
+
+migrate:
+ @poetry run ./manage.py migrate
+
+static:
+ @poetry run ./manage.py collectstatic
+
+sh:
+ @poetry run ./manage.py shell
+
+dev-deps:
+ @poetry install
+
+prod-deps:
+ @poetry install --no-dev -Ewsgi
+
+.POSIX:
+.SUFFIXES:
+.PHONY: all start-django migrate static sh dev-deps prod-deps
diff --git a/README.md b/README.md
@@ -0,0 +1,81 @@
+# Django Base
+A project template to bootstrap common projects.
+
+## Getting Started
+Chose one of the stage you want to bootstrap and run the commands.
+
+**development**
+```
+make dev-deps
+cp .ex/dev.py base/settings/
+# edit base/settings/dev.py
+make migrate
+make
+```
+
+**production**
+```
+make prod-deps
+cp .ex/prod.py base/settings/
+# edit base/settings/prod.py
+make migrate
+make static
+# set up a wsgi daemon and a fcgi daemon
+```
+
+
+## Project Structure
+Important project files:
+
+<dl>
+<dt>/base/</dt>
+<dd>Contains the entrypoint of the project. It has the settings, route definitions, and list of enabled apps.</dd>
+
+<dt>/page/</dt>
+<dd>This is a demo app that contains possible common pages across projects.</dd>
+
+<dt>/templ/</dt>
+<dd>Contains all the template files.</dd>
+
+<dt>/static/</dt>
+<dd>Contains all the static files.</dd>
+
+<dt>/.ex/</dt>
+<dd>Contains all the example files needed to bootstrap development or production stage.</dt>
+
+<dt>/pyproject.toml, /poetry.lock
+<dd>Dependency management files.</dd>
+
+<dt>/manage.py</dt>
+<dd>Contains the Django-specific commands.</dd>
+
+<dt>/.editorconfig</dt>
+<dd>You know what to do!</dd>
+
+<dt>/Makefile</dt>
+<dd>It has common shortcuts to manage the project. Checkout the «Make Targets» section.</dd>
+</dl>
+
+
+## Make Targets
+Here is a list of make(1) targets:
+
+<dl>
+<dt>all, or the default target</dt>
+<dd>It just runs the project.</dd>
+
+<dt>dev-deps</dt>
+<dd>Installs all the development dependencies.</dd>
+
+<dt>prod-deps</dt>
+<dd>Installs all the production dependencies.</dd>
+
+<dt>sh</dt>
+<dd>A shortcut for the «shell» command in manage.py.</dd>
+
+<dt>migrate</dt>
+<dd>Runs the «migrate» command in manage.py.</dd>
+
+<dt>static</dt>
+<dd>Runs the «collectstatic» command in manage.py.</dd>
+</dl>
diff --git a/base/__init__.py b/base/__init__.py
diff --git a/base/asgi.py b/base/asgi.py
@@ -0,0 +1,7 @@
+import os
+
+from django.core.asgi import get_asgi_application
+
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings.common")
+application = get_asgi_application()
diff --git a/base/settings/__init__.py b/base/settings/__init__.py
@@ -0,0 +1 @@
+
diff --git a/base/settings/common.py b/base/settings/common.py
@@ -0,0 +1,106 @@
+from pathlib import Path
+
+
+BASE_DIR = Path(__file__).resolve().parent.parent.parent
+
+# must be after BASE_DIR (to prevent circular import)
+try:
+ from .prod import *
+except ImportError:
+ from .dev import *
+
+
+# apps
+INSTALLED_APPS = [
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
+
+ "base",
+ "page",
+]
+
+if DEBUG:
+ INSTALLED_APPS.append("debug_toolbar")
+
+
+# middleware
+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",
+]
+
+if DEBUG:
+ MIDDLEWARE.append("debug_toolbar.middleware.DebugToolbarMiddleware")
+
+
+# wsgi app object
+WSGI_APPLICATION = "base.wsgi.application"
+
+
+# routing and templating
+ROOT_URLCONF = "base.urls"
+
+TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [BASE_DIR / "templ"],
+ "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",
+ ],
+ "builtins": ["django.templatetags.static"],
+ },
+ },
+]
+
+
+# passwd validation
+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",
+ },
+]
+
+
+# i18n
+LANGUAGE_CODE = "tr-tr"
+TIME_ZONE = "Europe/Istanbul"
+USE_I18N = True
+USE_L10N = True
+USE_TZ = True
+
+
+# assets/static files
+STATICFILES_DIRS = [BASE_DIR / "static"]
+
+STATIC_URL = "/static/"
+STATIC_ROOT = BASE_DIR / "asset/static"
+
+MEDIA_URL = "/media/"
+MEDIA_ROOT = BASE_DIR / "asset/media"
+
+
+# default pk type
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
diff --git a/base/urls.py b/base/urls.py
@@ -0,0 +1,20 @@
+from django.conf import settings
+from django.conf.urls.static import static
+from django.contrib import admin
+from django.urls import path, include
+from django.shortcuts import redirect
+
+
+urlpatterns = [
+ path("", lambda _: redirect("page:home", permanent=True)),
+ path("yonetici/", admin.site.urls),
+ path("sayfa/", include("page.urls")),
+]
+
+if settings.DEBUG:
+ import debug_toolbar
+
+ urlpatterns += [
+ path("__debug__/", include(debug_toolbar.urls)),
+ ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+
diff --git a/base/wsgi.py b/base/wsgi.py
@@ -0,0 +1,7 @@
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings.common")
+application = get_wsgi_application()
diff --git a/manage.py b/manage.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings.common")
+ try:
+ from django.core.management import execute_from_command_line
+ from django.core.management.commands.runserver import Command as runserver
+ from base.settings import common
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ runserver.default_port = getattr(common, "PORT", "8000")
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/page/__init__.py b/page/__init__.py
diff --git a/page/admin.py b/page/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/page/apps.py b/page/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class PageConfig(AppConfig):
+ default_auto_field = "django.db.models.BigAutoField"
+ name = "page"
diff --git a/page/migrations/__init__.py b/page/migrations/__init__.py
diff --git a/page/models.py b/page/models.py
@@ -0,0 +1 @@
+from django.db import models
diff --git a/page/tests.py b/page/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/page/urls.py b/page/urls.py
@@ -0,0 +1,12 @@
+from django.urls import path
+
+from . import views as v
+
+
+app_name = "page"
+
+urlpatterns = [
+ path("ana-sayfa/", v.home, name="home"),
+ path("hakkimizda/", v.about, name="about"),
+ path("iletisim/", v.contact, name="contact"),
+]
diff --git a/page/views.py b/page/views.py
@@ -0,0 +1,11 @@
+from django.shortcuts import render
+
+
+def home(r):
+ return render(r, "page/home.html")
+
+def about(r):
+ return render(r, "page/about.html")
+
+def contact(r):
+ return render(r, "page/contact.html")
diff --git a/poetry.lock b/poetry.lock
@@ -0,0 +1,119 @@
+[[package]]
+name = "asgiref"
+version = "3.4.0"
+description = "ASGI specs, helper code, and adapters"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
+
+[package.extras]
+tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
+
+[[package]]
+name = "django"
+version = "3.2.4"
+description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+asgiref = ">=3.3.2,<4"
+pytz = "*"
+sqlparse = ">=0.2.2"
+
+[package.extras]
+argon2 = ["argon2-cffi (>=19.1.0)"]
+bcrypt = ["bcrypt"]
+
+[[package]]
+name = "django-debug-toolbar"
+version = "3.2.1"
+description = "A configurable set of panels that display various debug information about the current request/response."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+Django = ">=2.2"
+sqlparse = ">=0.2.0"
+
+[[package]]
+name = "gunicorn"
+version = "20.1.0"
+description = "WSGI HTTP Server for UNIX"
+category = "main"
+optional = true
+python-versions = ">=3.5"
+
+[package.extras]
+eventlet = ["eventlet (>=0.24.1)"]
+gevent = ["gevent (>=1.4.0)"]
+setproctitle = ["setproctitle"]
+tornado = ["tornado (>=0.2)"]
+
+[[package]]
+name = "pytz"
+version = "2021.1"
+description = "World timezone definitions, modern and historical"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "sqlparse"
+version = "0.4.1"
+description = "A non-validating SQL parser."
+category = "main"
+optional = false
+python-versions = ">=3.5"
+
+[[package]]
+name = "typing-extensions"
+version = "3.10.0.0"
+description = "Backported and Experimental Type Hints for Python 3.5+"
+category = "main"
+optional = false
+python-versions = "*"
+
+[extras]
+wsgi = ["gunicorn"]
+
+[metadata]
+lock-version = "1.1"
+python-versions = "^3.6"
+content-hash = "cfb60b5f983299a6b29cd06a858b656c93972f586a78baecbdaa421c77043575"
+
+[metadata.files]
+asgiref = [
+ {file = "asgiref-3.4.0-py3-none-any.whl", hash = "sha256:d36fa91dd90e3aa3c81a6bd426ccc8fb20bd3d22b0cf14a12800289e9c3e2563"},
+ {file = "asgiref-3.4.0.tar.gz", hash = "sha256:05914d0fa65a21711e732adc6572edad6c8da5f1435c3f0c060689ced5e85195"},
+]
+django = [
+ {file = "Django-3.2.4-py3-none-any.whl", hash = "sha256:ea735cbbbb3b2fba6d4da4784a0043d84c67c92f1fdf15ad6db69900e792c10f"},
+ {file = "Django-3.2.4.tar.gz", hash = "sha256:66c9d8db8cc6fe938a28b7887c1596e42d522e27618562517cc8929eb7e7f296"},
+]
+django-debug-toolbar = [
+ {file = "django-debug-toolbar-3.2.1.tar.gz", hash = "sha256:a5ff2a54f24bf88286f9872836081078f4baa843dc3735ee88524e89f8821e33"},
+ {file = "django_debug_toolbar-3.2.1-py3-none-any.whl", hash = "sha256:e759e63e3fe2d3110e0e519639c166816368701eab4a47fed75d7de7018467b9"},
+]
+gunicorn = [
+ {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
+ {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
+]
+pytz = [
+ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
+ {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
+]
+sqlparse = [
+ {file = "sqlparse-0.4.1-py3-none-any.whl", hash = "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0"},
+ {file = "sqlparse-0.4.1.tar.gz", hash = "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8"},
+]
+typing-extensions = [
+ {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
+ {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
+ {file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
+]
diff --git a/pyproject.toml b/pyproject.toml
@@ -0,0 +1,20 @@
+[tool.poetry]
+name = "djbase"
+version = "0.1.0"
+description = "django base"
+authors = ["srfsh <srfsh@sonu.ch>"]
+
+[tool.poetry.dependencies]
+python = "^3.6"
+Django = "^3.2.4"
+gunicorn = {version = "^20.1.0", optional = true}
+
+[tool.poetry.dev-dependencies]
+django-debug-toolbar = {version = "^3.2.1"}
+
+[tool.poetry.extras]
+wsgi = ["gunicorn"]
+
+[build-system]
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
diff --git a/static/base/css/style.css b/static/base/css/style.css
diff --git a/static/base/img/icon.ico b/static/base/img/icon.ico
Binary files differ.
diff --git a/static/base/js/script.js b/static/base/js/script.js
diff --git a/templ/base/footer.html b/templ/base/footer.html
@@ -0,0 +1,3 @@
+<footer>
+ © 2021
+</footer>
diff --git a/templ/base/layout.html b/templ/base/layout.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html lang="tr-tr">
+<head>
+ <meta charset="utf-8"/>
+ <title>Djang Base</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
+ <link rel="icon" href="{% static 'base/img/icon.ico' %}"/>
+ <link rel="stylesheet" href="{% static 'base/css/style.css' %}"/>
+ <script defer src="{% static 'base/js/script.js' %}"></script>
+</head>
+<body>
+ {% include "base/navbar.html" %}
+ <main>{% block main %}{% endblock %}</main>
+ {% include "base/footer.html" %}
+</body>
+</html>
diff --git a/templ/base/navbar.html b/templ/base/navbar.html
@@ -0,0 +1,7 @@
+<nav>
+ <ul>
+ <li><a href="{% url 'page:home' %}">home</a></li>
+ <li><a href="{% url 'page:contact' %}">contact</a></li>
+ <li><a href="{% url 'page:about' %}">about</a></li>
+ </ul>
+</nav>
diff --git a/templ/page/about.html b/templ/page/about.html
@@ -0,0 +1,5 @@
+{% extends "base/layout.html" %}
+
+{% block main %}
+about us
+{% endblock %}
diff --git a/templ/page/contact.html b/templ/page/contact.html
@@ -0,0 +1,5 @@
+{% extends "base/layout.html" %}
+
+{% block main %}
+<p>contact me: <a href="mailto:awesome@example.com">my awesome email address</a></p>
+{% endblock %}
diff --git a/templ/page/home.html b/templ/page/home.html
@@ -0,0 +1,6 @@
+{% extends "base/layout.html" %}
+
+{% block main %}
+<h1>title</h1>
+<p>paragraph</p>
+{% endblock %}