visit
//github.com/mrShahsafi/Edu/tree/master/djnagoForFun/djnagoForFun/settings
When you are developing your Django project, and after each new web-app you’ll notice you have a lot in your settings.py and finding and managing your configs is harder than yesterday.
As you might notice, when you are calling the very famous manage.py Django’s entry-point command, it will try to create DJANGO_SETTINGS_MODULE and set PROJECT_NAME.settings to it.
What I do, I convert the settings.py to a python module with the
Until now we can include three files in our settings module
base.py:
from pathlib import Path
import os # Do not delete this
# Your everywhere service name
SITE_NAME = ""
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv(
"DJANGO_KEY",
default=“”,
)
# Application definition
DEFAULT_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
THIRD_PARTY_APPS = []
CREATED_APPS = []
INSTALLED_APPS = DEFAULT_APPS + CREATED_APPS + THIRD_PARTY_APPS
MIDDLEWARE = []
ROOT_URLCONF =
TEMPLATES =
WSGI_APPLICATION =
AUTH_PASSWORD_VALIDATORS =
# Internationalization
…
# Static files (CSS, JavaScript, Images)
…
if not os.path.exists("logs"):
os.makedirs(os.path.join(BASE_DIR, "logs"))
development.py
from .base import *
# import socket # only if you haven't already imported this
DEBUG = True
ALLOWED_HOSTS = [
"localhost",
"127.0.0.1",
]
try:
from .local import *
except Exception:
pass
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
INSTALLED_APPS += [
"debug_toolbar",
# 'django_extensions'
]
MIDDLEWARE += [
"debug_toolbar.middleware.DebugToolbarMiddleware",
]
"""
These commented config will use \
when you are running the project on Docker.
"""
# hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
# INTERNAL_IPS = [ip[:-1] + "1" for ip in ips] + ["127.0.0.1", "10.0.2.2"]
INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"]
You might notice the local.py file that I include here , we’ll get into it later.
production.py
from .base import *
DEBUG = False
ALLOWED_HOSTS = [#YOUR_PRODUCTION_HOSTS_ADDRESSESS]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": os.getenv("DB_NAME", default="db"),
"USER": os.getenv("DB_USER", default="root"),
"PASSWORD": os.getenv("DB_PASS", default="root-password"),
"HOST": "postgres",
"PORT": "5432",
}
}
When we have our three files, we must somehow manage them at the entry point of the settings module and I mean the
init .py:
from os import getenv
env = getenv("DJANGO_ENV", default="development")
if env == "production":
print("You Are in the Production Mode.")
from .porduction import *
elif env == "development":
print("Warning! You Are in the Development Mode.\nDo Not use in any server.")
from .development import *
base.py
# At the end of your base.py
try:
from .drf_settings import *
except Exception:
pass
drf_settings.py:
from datetime import timedelta
from .base import SITE_NAME
REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_PARSER_CLASSES": (
"rest_framework.parsers.JSONParser",
"rest_framework.parsers.MultiPartParser",
"rest_framework.parsers.FileUploadParser",
),
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": (
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
),
"DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
"DEFAULT_PAGINATION_CLASS": "core.pagination.CustomPagination",
"PAGE_SIZE": 9,
# "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.AcceptHeaderVersioning", # when we active versioning the swagger ui brakes!= ""
"TEST_REQUEST_DEFAULT_FORMAT": "json",
"EXCEPTION_HANDLER": "core.errors.custom_exception_handler",
}
: It will manage your project transactions, errors, etc. and report to you weekly
: For the development, it offers very good tools like the SQL query time, available signals and etc.
: A slick app that supports automatic or manual queryset caching and automatic granular event-driven invalidation.
: Django application that provides utilities for preventing automated form spam.
: Django-seed uses the library to generate test data for your Django models. This has been “hard-forked” from in order to support newer versions of Python and Django
: Django-filter is a reusable Django application allowing users to declaratively add dynamic QuerySet filtering from URL parameters.
: Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication. And most of the time, it will satisfy your requirements
: Sane and flexible schema generation for If your are using and writing APIs.
: Place models and worldwide place data for Django.
# The project Todo List items
---
- [ ] un-done Task
- [x] done Task
---
## Models
## APIs
- [ ] django channels middleware for JwtAuth
## Others
## Bugs
## Emails
- [x] Forgot Password link
## Tests
- [ ] model tests for Advertisement
## NOTES
Django comes with a very useful topic: . By following these instructions, your custom command will be like this
python manage.py my_custom_command
For example, maybe you want to create fake_user command or test your machine dependencies before you perform a special action. In this way, all your commands have one structure both for writing and execution. And believe me, it is very important when your project becomes a little complex.
All you need just a file that contains all these messages as variables.
Use abstract model that contains is_deleted attribute with the False default value and try to inherit all your other models from this common model.
All you need to do for bulk delete is turn the is_deleted flag of your instances to True and make sure you filter your querysets with:
qs = Model.objects.filter(is_deleted=Flase)
you need to break it to separate files, especially when it comes to views.py.
Lets say we have a registration view called RegistrationApi
, you can write the registrations logics in auth.logics.registration_api_logic
and use it in your view.
This is the power of the Django.
Separate your serializers by their identities
are better than just having MyModelSerializer.
introduced concept to provide initial data for models.
Always have the fixtures directory; it helps you to store all your fixed files and data in specific place.
Conclusion:
Hope you’ll enjoy using Django with these discussed concepts and structures.Also, I’ve prepared a service that could generate better projects and web-apps for you. You can check it out .
Thanks.