Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add django example #445

Merged
merged 3 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/python-django/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
35 changes: 35 additions & 0 deletions examples/python-django/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# `devenv-django`

This example demonstrates using [devenv.sh](https://devenv.sh/) alongside [`poetry`](https://python-poetry.org/docs/) for building a `Django` development environment.

Specifically, `devenv` uses `nix` to install system level packages like `postgresql_14` from `nixpkgs` & `poetry` uses `pip` to install `Python` packages from `pypi`

> **Note**: Also see https://github.com/nix-community/poetry2nix/ which converts `poetry` projects to `nix`, this example uses both tools separately


---


## Installation

Install [`devenv.sh`](https://devenv.sh/getting-started)


---


## Usage

`devenv` enables defining scripts in `devenv.nix` that are automatically added to the shell path ...

- Launch a development server via `devenv up`

- Launch a development shell via `devenv shell`

> [!WARNING]
> This example depends on `Postgres`, so please ensure that it's running via `devenv up` (or automatically via `direnv`) before running `python manage.py ...`

- Run tests via `devenv test`

> [!TIP]
> See [`devenv.sh`](https://devenv.sh/tests/) for more information)
43 changes: 43 additions & 0 deletions examples/python-django/devenv.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{ pkgs, config, ... }:

let
db_user = "postgres";
db_host = "localhost";
db_port = "5432";
db_name = "db";
in
{
packages = [ pkgs.git pkgs.postgresql_14 ];

languages.python = {
enable = true;
package = pkgs.python310;
poetry.enable = true;
};

env = {
DATABASE_URL = "postgres://${db_user}@/${db_name}?host=${config.env.PGHOST}";
DEBUG = true;
SECRET_KEY = "123";
STATIC_ROOT = "/tmp";
};

services.postgres = {
enable = true;
initialScript = "CREATE USER ${db_user} SUPERUSER;";
initialDatabases = [{ name = db_name; }];
listen_addresses = db_host;
};

processes = {
runserver.exec = ''
python manage.py runserver
'';
};

enterTest = ''
wait_for_port ${db_port}
python manage.py test
'';

}
22 changes: 22 additions & 0 deletions examples/python-django/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/nix/store/iw1vmh509hcbby8dbpsaanbri4zsq7dj-python3-3.10.10/bin/python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
try:
from django.core.management import execute_from_command_line
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
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()
Empty file.
6 changes: 6 additions & 0 deletions examples/python-django/myapp/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class MyAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
Empty file.
5 changes: 5 additions & 0 deletions examples/python-django/myapp/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.test import TestCase

class Test(TestCase):
def test(self):
self.assertEqual(1, 1)
Empty file.
16 changes: 16 additions & 0 deletions examples/python-django/myproject/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for myproject project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

application = get_asgi_application()
130 changes: 130 additions & 0 deletions examples/python-django/myproject/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""
Django settings for myproject project.

Generated by 'django-admin startproject' using Django 3.2.18.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import warnings

from pathlib import Path

import environ


env = environ.Env(DEBUG=(bool, False))

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

SECRET_KEY = env('SECRET_KEY')

DEBUG = env('DEBUG')

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

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 = 'myproject.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',
],
},
},
]

WSGI_APPLICATION = 'myproject.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

# NOTE: don't store credentials in settings file
# ... this is just a test case to myproject the issue so it's fine
# ... in a real project, use environment variables or a secrets file
# ... via something like django-environ or python-dotenv
DATABASES = {
'default': env.db()
}


# Password validation
# https://docs.djangoproject.com/en/3.2/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.2/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.2/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = env("STATIC_ROOT")

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
21 changes: 21 additions & 0 deletions examples/python-django/myproject/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""myproject URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

urlpatterns = [
path('admin/', admin.site.urls),
]
16 changes: 16 additions & 0 deletions examples/python-django/myproject/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
WSGI config for myproject project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

application = get_wsgi_application()
Loading
Loading