diff --git a/.env_example b/.env_example new file mode 100644 index 0000000..361a9f9 --- /dev/null +++ b/.env_example @@ -0,0 +1,6 @@ +# django +DJANGO_DEBUG=off +DJANGO_SECRET_KEY= + +# postgres +DATABASE_URL="postgres://user:password@localhost:5432/database" \ No newline at end of file diff --git a/.gitignore b/.gitignore index ae0e35b..5345a25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .DS_Store .idea -uploads +kodilan/media # Django # *.log @@ -8,7 +8,6 @@ uploads *.pyc __pycache__ db.sqlite3 -media # Backup files # *.bak diff --git a/posts/__init__.py b/config/__init__.py similarity index 100% rename from posts/__init__.py rename to config/__init__.py diff --git a/kodilan/asgi.py b/config/asgi.py similarity index 100% rename from kodilan/asgi.py rename to config/asgi.py diff --git a/posts/migrations/__init__.py b/config/settings/__init__.py similarity index 100% rename from posts/migrations/__init__.py rename to config/settings/__init__.py diff --git a/config/settings/base.py b/config/settings/base.py new file mode 100644 index 0000000..480fbe4 --- /dev/null +++ b/config/settings/base.py @@ -0,0 +1,136 @@ +""" +Django settings for config project. + +Generated by 'django-admin startproject' using Django 3.0.6. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.0/ref/settings/ +""" + +import os + +import environ + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +ROOT_DIR = environ.Path(__file__) - 3 +APPS_DIR = ROOT_DIR.path("kodilan") + +env = environ.Env() + + +READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=True) +if READ_DOT_ENV_FILE: + # OS environment variables take precedence over variables from .env + env.read_env(str(ROOT_DIR.path(".env"))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = env( + "DJANGO_SECRET_KEY", default="adsbz3wt%#b3n&-k2m0woxk5b-tvaz-8=3uuoim_y(j$z=-0+n" +) +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = env.bool("DJANGO_DEBUG", False) + +# Application definition + +DJANGO_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", +] + +THIRD_PARTY_APPS = ["rest_framework"] + +LOCAL_APPS = ["kodilan.posts.apps.PostsConfig"] + +INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS + + +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 = "config.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [str(ROOT_DIR.path("templates"))], + "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", + ], + }, + }, +] + +WSGI_APPLICATION = "config.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases + +DATABASES = {"default": env.db("DATABASE_URL")} + +# Password validation +# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators + +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",}, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.0/topics/i18n/ + +LANGUAGE_CODE = "en-us" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.0/howto/static-files/ + +STATIC_URL = "/static/" + +STATICFILES_DIRS = [str(APPS_DIR.path("static"))] + +MEDIA_ROOT = str(APPS_DIR("media")) + +MEDIA_URL = "/m/" + + +REST_FRAMEWORK = { + "DEFAULT_PAGINATION_CLASS": "kodilan.baseapp.pagination.StandardResultsSetPagination", + "PAGE_SIZE": 10, +} diff --git a/config/settings/dev.py b/config/settings/dev.py new file mode 100644 index 0000000..a01b72a --- /dev/null +++ b/config/settings/dev.py @@ -0,0 +1,3 @@ +from .base import * # noqa + +ALLOWED_HOSTS = ["*"] diff --git a/config/settings/prod.py b/config/settings/prod.py new file mode 100644 index 0000000..1f253bf --- /dev/null +++ b/config/settings/prod.py @@ -0,0 +1,5 @@ +from .base import * # noqa + +SECRET_KEY = env("DJANGO_SECRET_KEY") + +ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS") diff --git a/kodilan/urls.py b/config/urls.py similarity index 97% rename from kodilan/urls.py rename to config/urls.py index 773ea9b..88ca0bd 100644 --- a/kodilan/urls.py +++ b/config/urls.py @@ -16,7 +16,7 @@ from django.contrib import admin from django.urls import include, path from rest_framework import routers -from posts import views +from kodilan.posts import views router = routers.DefaultRouter() diff --git a/kodilan/wsgi.py b/config/wsgi.py similarity index 73% rename from kodilan/wsgi.py rename to config/wsgi.py index 833fc03..b255544 100644 --- a/kodilan/wsgi.py +++ b/config/wsgi.py @@ -1,5 +1,5 @@ """ -WSGI config for kodilan project. +WSGI config for config project. It exposes the WSGI callable as a module-level variable named ``application``. @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kodilan.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev') application = get_wsgi_application() diff --git a/uploads/.gitkeep b/kodilan/baseapp/__init__.py similarity index 100% rename from uploads/.gitkeep rename to kodilan/baseapp/__init__.py diff --git a/kodilan/mail.py b/kodilan/baseapp/mail.py similarity index 54% rename from kodilan/mail.py rename to kodilan/baseapp/mail.py index a2cd156..2429e0c 100644 --- a/kodilan/mail.py +++ b/kodilan/baseapp/mail.py @@ -4,23 +4,26 @@ def do_mail(email, title, theme, variables): - msg_plain = render_to_string('mail/{}.txt'.format(theme), variables) - msg_html = render_to_string('mail/{}.html'.format(theme), variables) + msg_plain = render_to_string("mail/{}.txt".format(theme), variables) + msg_html = render_to_string("mail/{}.html".format(theme), variables) try: send_mail( - 'Kodilan - ' + title, + "Kodilan - " + title, msg_plain, getattr(settings, "SENDER_MAIL", ""), [email], fail_silently=False, - html_message=msg_html + html_message=msg_html, ) except ConnectionRefusedError as e: - print('There was an error sending an email: ', e) - pass + print("There was an error sending an email: ", e) # todo: create post will update def send_activation(email, first_name, last_name, token): - do_mail(email, "İlan Onay", "activation", - {'first_name': first_name, 'last_name': last_name, 'code': token}) + do_mail( + email, + "İlan Onay", + "activation", + {"first_name": first_name, "last_name": last_name, "code": token}, + ) diff --git a/kodilan/baseapp/pagination.py b/kodilan/baseapp/pagination.py new file mode 100644 index 0000000..22463ae --- /dev/null +++ b/kodilan/baseapp/pagination.py @@ -0,0 +1,21 @@ +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response + + +class StandardResultsSetPagination(PageNumberPagination): + page_size = 20 + page_size_query_param = "page_size" + max_page_size = 1000 + + def get_paginated_response(self, data): + return Response( + { + "links": { + "next": self.get_next_link(), + "previous": self.get_previous_link(), + }, + "count": self.page.paginator.count, + "results": data, + "page_number": self.page.number, + } + ) diff --git a/kodilan/customs.py b/kodilan/customs.py deleted file mode 100644 index 69c19d6..0000000 --- a/kodilan/customs.py +++ /dev/null @@ -1,19 +0,0 @@ -from rest_framework.pagination import PageNumberPagination -from rest_framework.response import Response - - -class StandardResultsSetPagination(PageNumberPagination): - page_size = 20 - page_size_query_param = 'page_size' - max_page_size = 1000 - - def get_paginated_response(self, data): - return Response({ - 'links': { - 'next': self.get_next_link(), - 'previous': self.get_previous_link() - }, - 'count': self.page.paginator.count, - 'results': data, - 'page_number': self.page.number, - }) \ No newline at end of file diff --git a/kodilan/posts/__init__.py b/kodilan/posts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/posts/admin.py b/kodilan/posts/admin.py similarity index 100% rename from posts/admin.py rename to kodilan/posts/admin.py diff --git a/posts/apps.py b/kodilan/posts/apps.py similarity index 70% rename from posts/apps.py rename to kodilan/posts/apps.py index 2c2b982..7382b12 100644 --- a/posts/apps.py +++ b/kodilan/posts/apps.py @@ -2,4 +2,4 @@ class PostsConfig(AppConfig): - name = 'posts' + name = 'kodilan.posts' diff --git a/posts/filters.py b/kodilan/posts/filters.py similarity index 100% rename from posts/filters.py rename to kodilan/posts/filters.py diff --git a/posts/migrations/0001_initial.py b/kodilan/posts/migrations/0001_initial.py similarity index 100% rename from posts/migrations/0001_initial.py rename to kodilan/posts/migrations/0001_initial.py diff --git a/posts/migrations/0002_auto_20200601_1846.py b/kodilan/posts/migrations/0002_auto_20200601_1846.py similarity index 100% rename from posts/migrations/0002_auto_20200601_1846.py rename to kodilan/posts/migrations/0002_auto_20200601_1846.py diff --git a/posts/migrations/0003_auto_20200601_1853.py b/kodilan/posts/migrations/0003_auto_20200601_1853.py similarity index 100% rename from posts/migrations/0003_auto_20200601_1853.py rename to kodilan/posts/migrations/0003_auto_20200601_1853.py diff --git a/posts/migrations/0004_post.py b/kodilan/posts/migrations/0004_post.py similarity index 100% rename from posts/migrations/0004_post.py rename to kodilan/posts/migrations/0004_post.py diff --git a/posts/migrations/0005_auto_20200601_1909.py b/kodilan/posts/migrations/0005_auto_20200601_1909.py similarity index 100% rename from posts/migrations/0005_auto_20200601_1909.py rename to kodilan/posts/migrations/0005_auto_20200601_1909.py diff --git a/posts/migrations/0006_auto_20200601_1931.py b/kodilan/posts/migrations/0006_auto_20200601_1931.py similarity index 100% rename from posts/migrations/0006_auto_20200601_1931.py rename to kodilan/posts/migrations/0006_auto_20200601_1931.py diff --git a/posts/migrations/0007_auto_20200601_1934.py b/kodilan/posts/migrations/0007_auto_20200601_1934.py similarity index 100% rename from posts/migrations/0007_auto_20200601_1934.py rename to kodilan/posts/migrations/0007_auto_20200601_1934.py diff --git a/kodilan/posts/migrations/0008_auto_20200604_1136.py b/kodilan/posts/migrations/0008_auto_20200604_1136.py new file mode 100644 index 0000000..54c30ab --- /dev/null +++ b/kodilan/posts/migrations/0008_auto_20200604_1136.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.6 on 2020-06-04 11:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('posts', '0007_auto_20200601_1934'), + ] + + operations = [ + migrations.AlterField( + model_name='post', + name='status', + field=models.PositiveSmallIntegerField(choices=[(0, 'ONAYLANMADI'), (1, 'ONAYLANDI'), (2, 'YAYINLANMADI')]), + ), + ] diff --git a/kodilan/posts/migrations/__init__.py b/kodilan/posts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/posts/models.py b/kodilan/posts/models.py similarity index 100% rename from posts/models.py rename to kodilan/posts/models.py diff --git a/posts/serializers.py b/kodilan/posts/serializers.py similarity index 100% rename from posts/serializers.py rename to kodilan/posts/serializers.py diff --git a/posts/tests.py b/kodilan/posts/tests.py similarity index 100% rename from posts/tests.py rename to kodilan/posts/tests.py diff --git a/posts/views.py b/kodilan/posts/views.py similarity index 100% rename from posts/views.py rename to kodilan/posts/views.py diff --git a/kodilan/settings.py b/kodilan/settings.py deleted file mode 100644 index e914225..0000000 --- a/kodilan/settings.py +++ /dev/null @@ -1,136 +0,0 @@ -""" -Django settings for kodilan project. - -Generated by 'django-admin startproject' using Django 3.0.6. - -For more information on this file, see -https://docs.djangoproject.com/en/3.0/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.0/ref/settings/ -""" - -import os - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'adsbz3wt%#b3n&-k2m0woxk5b-tvaz-8=3uuoim_y(j$z=-0+n' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = [ - 'posts.apps.PostsConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'rest_framework', -] - -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 = 'kodilan.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'templates')] - , - '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', - ], - }, - }, -] - -WSGI_APPLICATION = 'kodilan.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.0/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'kodilan', - 'USER': 'emir', - 'PASSWORD': '', - 'HOST': '127.0.0.1', - 'PORT': '5432', - } -} - - -# Password validation -# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators - -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', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/3.0/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.0/howto/static-files/ - -STATIC_URL = '/static/' - -STATICFILES_DIRS = [ - os.path.join(BASE_DIR, "uploads"), -] - -REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_CLASS': 'kodilan.customs.StandardResultsSetPagination', - 'PAGE_SIZE': 10 -} diff --git a/manage.py b/manage.py index cebab22..f2190b5 100755 --- a/manage.py +++ b/manage.py @@ -5,7 +5,7 @@ def main(): - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kodilan.settings') + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev') try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/requirements.txt b/requirements.txt index 2883bbf..3450beb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ Pillow==7.1.2 psycopg2 pytz==2020.1 sqlparse==0.3.1 +django-environ==0.4.5 django-cors-headers django-filter django-filters