docs: rebuild site based on latest readme

This commit is contained in:
Saqibur Rahman 2024-11-05 15:36:20 +06:00
parent 0187b89906
commit 9814b32116
7 changed files with 550 additions and 444 deletions

View File

@ -215,3 +215,9 @@ defaults, but let's hope we have time to work on it on the `cookiecutter` branch
- [Build APIs You Won't Hate](https://apisyouwonthate.com/books/build-apis-you-wont-hate/)
- [Tuxedo Style Guides](https://github.com/saqibur/tuxedo)
- [Django Anti Patterns](https://www.django-antipatterns.com/)
## Documentation
* Copy README.md to `mkdocs` folder
* Build: `mkdocs build -d docs`
* Serve: `mkdocs serve`

View File

@ -2,94 +2,94 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="This is a template/project structure for developing django-based applications - either strictly through the django-rest-framework or just django.">
<meta name="description" content="This is a template/project structure for developing django-based applications - using django-rest-framework along with django.">
<meta name="author" content="Saqibur Rahman">
<link rel="icon" href="/saqibur/django-project-structure/assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.4.12">
<meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.4.12">
<title>Django Project Structure</title>
<link rel="stylesheet" href="/saqibur/django-project-structure/assets/stylesheets/main.fad675c6.min.css">
<link rel="stylesheet" href="/saqibur/django-project-structure/assets/stylesheets/palette.356b1318.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("/saqibur/django-project-structure/",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script>__md_scope=new URL("/saqibur/django-project-structure/",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
</div>
<div data-md-component="announce">
</div>
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="/saqibur/django-project-structure/." title="Django Project Structure" class="md-header__button md-logo" aria-label="Django Project Structure" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
@ -101,20 +101,20 @@
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
@ -123,19 +123,19 @@
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
@ -149,12 +149,12 @@
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/saqibur/django-project-structure" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
@ -162,45 +162,45 @@
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="/saqibur/django-project-structure/." title="Django Project Structure" class="md-nav__button md-logo" aria-label="Django Project Structure" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg>
</a>
Django Project Structure
</label>
<div class="md-nav__source">
<a href="https://github.com/saqibur/django-project-structure" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
@ -208,99 +208,99 @@
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/saqibur/django-project-structure/." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>404 - Not found</h1>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2022 - 2023 Saqibur Rahman
Copyright &copy; 2022 - 2024 Saqibur Rahman
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "/saqibur/django-project-structure/", "features": [], "search": "/saqibur/django-project-structure/assets/javascripts/workers/search.f886a092.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="/saqibur/django-project-structure/assets/javascripts/bundle.6c14ae12.min.js"></script>
</body>
</html>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://github.com/saqibur/django-project-structure/</loc>
<lastmod>2023-11-26</lastmod>
<lastmod>2024-11-05</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>
</urlset>

Binary file not shown.

View File

@ -1,6 +1,6 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Python 3.10.8](https://img.shields.io/badge/python-3.10.8-blue.svg)](https://www.python.org/downloads/release/python-3108//)
[![Python 3.12.3](https://img.shields.io/badge/python-3.12.3-blue.svg)](https://www.python.org/downloads/release/python-3123/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://pre-commit.com/)
![Django](https://img.shields.io/badge/django-%23092E20.svg?style=for-the-badge&logo=django&logoColor=white)
![DjangoREST](https://img.shields.io/badge/DJANGO-REST-ff1709?style=for-the-badge&logo=django&logoColor=white&color=ff1709&labelColor=gray)
@ -10,13 +10,21 @@
# Django Project Structure
This is a template/project structure for developing django-based applications -
either strictly through the `django-rest-framework` or just `django`.
using `django-rest-framework` along with `django`.
The project is meant to be easily clone-able, and used as the starter template
for the next big thing you develop. Note, this is a folder structure only, not
“best practices”.
## Some batteries included:
* [Django Storages](https://django-storages.readthedocs.io/en/stable/) - To integrate with different types of storages
* [Django Rest Framework](https://www.django-rest-framework.org/) - For API development
* [Django CORS Headers](https://github.com/adamchainz/django-cors-headers) - To allow requests from other origins
* [Sentry](https://docs.sentry.io/platforms/python/) - For crashes
* [Gunicorn](https://gunicorn.org/) - As a web server
## Getting Started
1. Since this is a template repository, simply hit "Use this template" on GitHub
and follow the instructions. Otherwise, you can just clone the repo, remove/add
@ -24,6 +32,20 @@ anything you see fit.
1. Run the project using `python manage.py runserver` and you should see the
default success page provided by Django at
[http://127.0.0.1:8000/](http://127.0.0.1:8000/).
1. [Optional] If you want to configure database, in the `DATABASE` section of
`settings.py` we have added `postgresql` as the default `DATABASE` (As most of
the application are using it). You can roll back to the `sqlite` by adding the
following code snippet, removing the current one.
```bash
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
```
### Creating an App
1. Create a folder with the app name in `apps`. For example: `poll`
@ -34,60 +56,59 @@ project
## Project Tree
``` bash
.
├── apps
│ └── example # A django rest app
│ ├── api
│ │ ├── v1 # Only the "presentation" layer exists here.
├── apps/
│ └── example/ # A django rest app
│ ├── api/
│ │ ├── v1/ # Only the "presentation" layer exists here.
│ │ │ ├── __init__.py
│ │ │ ├── serializers.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ ├── v2 # Only the "presentation" layer exists here.
│ │ ├── v2 # Only the "presentation" layer exists here.
│ │ │ ├── __init__.py
│ │ │ ├── serializers.py
│ │ │ ├── urls.py
│ │ │ └── views.py
│ │ └── __init__.py
│ ├── fixtures # Constant "seeders" to populate your database
│ ├── management
│ │ ├── commands # Try and write some database seeders here
│ ├── fixtures/ # Constant "seeders" to populate your database
│ ├── management/
│ │ ├── commands/ # Try and write some database seeders here
│ │ │ └── command.py
│ │ └── __init__.py
│ ├── migrations
│ ├── migrations/
│ │ └── __init__.py
│ ├── templates # App-specific templates go here
│ ├── tests # All your integration and unit tests for an app go here.
│ ├── templates/ # App-specific templates go here
│ ├── tests/ # All your integration and unit tests for an app go here.
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ ├── services.py # Your business logic and data abstractions go here.
│ ├── services.py # Your business logic and data abstractions go here.
│ ├── urls.py
│ └── views.py
├── common # An optional folder containing common "stuff" for the entire project
├── config
│ ├── settings.py
│ ├── asgi.py
├── common/ # An optional folder containing common "stuff" for the entire project
├── config/
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── deployments # Isolate Dockerfiles and docker-compose files here.
├── docs
├── deployments/ # Isolate Dockerfiles and docker-compose files here.
├── docs/
│ ├── CHANGELOG.md
│ ├── CONTRIBUTING.md
│ ├── deployment.md
│ ├── local-development.md
│ └── swagger.yaml
├── requirements
│ ├── common.txt # Same for all environments
│ ├── development.txt # Only for a development server
│ ├── local.txt # Only for a local server (example: docs, performance testing, etc.)
│ └── production.txt # Production only
├── static # Your static files
├── .env.example # An example of your .env configurations. Add necessary comments.
├── static # Your static files
├── .gitignore # https://github.com/github/gitignore/blob/main/Python.gitignore
├── entrypoint.sh # Any bootstrapping necessary for your application
├── requirements/
│ ├── common.txt # Same for all environments
│ ├── development.txt # Only for a development server
│ ├── local.txt # Only for a local server (example: docs, performance testing, etc.)
│ └── production.txt # Production only
├── static/ # Your static files
├── .env.example # An example of your .env configurations. Add necessary comments.
├── .gitignore # https://github.com/github/gitignore/blob/main/Python.gitignore
├── entrypoint.sh # Any bootstrapping necessary for your application
├── manage.py
├── pytest.ini
└── README.md
@ -103,7 +124,7 @@ into any other project and itll work independently.
* A mother-folder containing all apps for our project. Congruent to any
JS-framework's `src` folder. If you really wanted to, you could even call it the
`src` folder. Again, it's up to you.
* An app can be a django template project, or an rest framework API.
* An app can be a django template project, or a rest framework API.
### `services`
* Well be writing business logic in services instead of anywhere else.
@ -148,7 +169,8 @@ endpoints to ensure full compatibility.
#### What's `v2` of an API?
Currently we're proposing that major changes to the following, constitutes a new API version:
Currently, we're proposing that major changes to the following constitutes a new
API version:
1. Representation of data, either for submission or retrieval
1. Major optimizations
1. Major code reorganization and code refactor
@ -173,6 +195,17 @@ you can check out the Django Rest Framework documentation at:
https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling
## FAQ
> Why not just make a cookiecutter out of this?
Honestly, GitHub templates are so much easier. It's a one-click solution and
you're good to go. If we want to turn this into a cookiecutter, we'd have to also
start deciding sensible defaults, for instance, sentry, DRF version, formatters,
linters, etc. And that's something better left to the developer. Although, I am
playing around with the idea of having a cookiecutter with those sensible
defaults, but let's hope we have time to work on it on the `cookiecutter` branch.
## References
- [Two Scoops of Django by Daniel and Audrey Feldroy](https://www.feldroy.com/books/two-scoops-of-django-3-x)
- [Django Best Practices](https://django-best-practices.readthedocs.io/en/latest/index.html)
@ -181,3 +214,4 @@ https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-han
- [Radoslav Georgiev - Django Structure for Scale and Longevity](https://www.youtube.com/watch?v=yG3ZdxBb1oo)
- [Build APIs You Won't Hate](https://apisyouwonthate.com/books/build-apis-you-wont-hate/)
- [Tuxedo Style Guides](https://github.com/saqibur/tuxedo)
- [Django Anti Patterns](https://www.django-antipatterns.com/)