@@ -0,0 +1,3 @@ | |||
# Default ignored files | |||
/workspace.xml |
@@ -0,0 +1,18 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="PYTHON_MODULE" version="4"> | |||
<component name="NewModuleRootManager"> | |||
<content url="file://$MODULE_DIR$" /> | |||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
</component> | |||
<component name="TemplatesService"> | |||
<option name="TEMPLATE_FOLDERS"> | |||
<list> | |||
<option value="$MODULE_DIR$/news/venv/lib/python3.7/site-packages/django/forms/templates" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="TestRunnerService"> | |||
<option name="PROJECT_TEST_RUNNER" value="Unittests" /> | |||
</component> | |||
</module> |
@@ -0,0 +1,6 @@ | |||
<component name="InspectionProjectProfileManager"> | |||
<settings> | |||
<option name="USE_PROJECT_PROFILE" value="false" /> | |||
<version value="1.0" /> | |||
</settings> | |||
</component> |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="JavaScriptSettings"> | |||
<option name="languageLevel" value="ES6" /> | |||
</component> | |||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" /> | |||
</project> |
@@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ProjectModuleManager"> | |||
<modules> | |||
<module fileurl="file://$PROJECT_DIR$/.idea/DjangoProjekt.iml" filepath="$PROJECT_DIR$/.idea/DjangoProjekt.iml" /> | |||
</modules> | |||
</component> | |||
</project> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,3 @@ | |||
# Default ignored files | |||
/workspace.xml |
@@ -0,0 +1,6 @@ | |||
<component name="InspectionProjectProfileManager"> | |||
<settings> | |||
<option name="USE_PROJECT_PROFILE" value="false" /> | |||
<version value="1.0" /> | |||
</settings> | |||
</component> |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="JavaScriptSettings"> | |||
<option name="languageLevel" value="ES6" /> | |||
</component> | |||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (news1)" project-jdk-type="Python SDK" /> | |||
</project> |
@@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ProjectModuleManager"> | |||
<modules> | |||
<module fileurl="file://$PROJECT_DIR$/.idea/news1.iml" filepath="$PROJECT_DIR$/.idea/news1.iml" /> | |||
</modules> | |||
</component> | |||
</project> |
@@ -0,0 +1,33 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="PYTHON_MODULE" version="4"> | |||
<component name="FacetManager"> | |||
<facet type="django" name="Django"> | |||
<configuration> | |||
<option name="rootFolder" value="$MODULE_DIR$" /> | |||
<option name="settingsModule" value="news1/settings.py" /> | |||
<option name="manageScript" value="$MODULE_DIR$/manage.py" /> | |||
<option name="environment" value="<map/>" /> | |||
<option name="doNotUseTestRunner" value="false" /> | |||
<option name="trackFilePattern" value="migrations" /> | |||
</configuration> | |||
</facet> | |||
</component> | |||
<component name="NewModuleRootManager"> | |||
<content url="file://$MODULE_DIR$"> | |||
<excludeFolder url="file://$MODULE_DIR$/venv" /> | |||
</content> | |||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
</component> | |||
<component name="TemplatesService"> | |||
<option name="TEMPLATE_CONFIGURATION" value="Django" /> | |||
<option name="TEMPLATE_FOLDERS"> | |||
<list> | |||
<option value="$MODULE_DIR$/templates" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="TestRunnerService"> | |||
<option name="PROJECT_TEST_RUNNER" value="Unittests" /> | |||
</component> | |||
</module> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,21 @@ | |||
#!/usr/bin/env python | |||
"""Django's command-line utility for administrative tasks.""" | |||
import os | |||
import sys | |||
def main(): | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'news1.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() |
@@ -0,0 +1,121 @@ | |||
""" | |||
Django settings for news1 project. | |||
Generated by 'django-admin startproject' using Django 2.2.7. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/2.2/topics/settings/ | |||
For the full list of settings and their values, see | |||
https://docs.djangoproject.com/en/2.2/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/2.2/howto/deployment/checklist/ | |||
# SECURITY WARNING: keep the secret key used in production secret! | |||
SECRET_KEY = 'f1dkv=9u-zlz&^x4!w&m8mcxar!+bz2law81)axx1qg-ngu4$u' | |||
# SECURITY WARNING: don't run with debug turned on in production! | |||
DEBUG = True | |||
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 = 'news1.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 = 'news1.wsgi.application' | |||
# Database | |||
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases | |||
DATABASES = { | |||
'default': { | |||
'ENGINE': 'django.db.backends.sqlite3', | |||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), | |||
} | |||
} | |||
# Password validation | |||
# https://docs.djangoproject.com/en/2.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/2.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/2.2/howto/static-files/ | |||
STATIC_URL = '/static/' |
@@ -0,0 +1,24 @@ | |||
"""news1 URL Configuration | |||
The `urlpatterns` list routes URLs to views. For more information please see: | |||
https://docs.djangoproject.com/en/2.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, include | |||
urlpatterns = [ | |||
path('', include('posts.urls')), | |||
path('posts/', include('posts.urls')), | |||
path('admin/', admin.site.urls), | |||
] |
@@ -0,0 +1,16 @@ | |||
""" | |||
WSGI config for news1 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/2.2/howto/deployment/wsgi/ | |||
""" | |||
import os | |||
from django.core.wsgi import get_wsgi_application | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'news1.settings') | |||
application = get_wsgi_application() |
@@ -0,0 +1,3 @@ | |||
from django.contrib import admin | |||
# Register your models here. |
@@ -0,0 +1,5 @@ | |||
from django.apps import AppConfig | |||
class PostsConfig(AppConfig): | |||
name = 'posts' |
@@ -0,0 +1,3 @@ | |||
from django.db import models | |||
# Create your models here. |
@@ -0,0 +1,3 @@ | |||
from django.test import TestCase | |||
# Create your tests here. |
@@ -0,0 +1,6 @@ | |||
from django.urls import path | |||
from . import views | |||
urlpatterns = [ | |||
path('', views.index, name='index') | |||
] |
@@ -0,0 +1,7 @@ | |||
from django.shortcuts import render | |||
from django.http import HttpResponse | |||
# Create your views here. | |||
def index(request): | |||
return HttpResponse("Posts Index") |
@@ -0,0 +1,231 @@ | |||
<# | |||
.Synopsis | |||
Activate a Python virtual environment for the current Powershell session. | |||
.Description | |||
Pushes the python executable for a virtual environment to the front of the | |||
$Env:PATH environment variable and sets the prompt to signify that you are | |||
in a Python virtual environment. Makes use of the command line switches as | |||
well as the `pyvenv.cfg` file values present in the virtual environment. | |||
.Parameter VenvDir | |||
Path to the directory that contains the virtual environment to activate. The | |||
default value for this is the parent of the directory that the Activate.ps1 | |||
script is located within. | |||
.Parameter Prompt | |||
The prompt prefix to display when this virtual environment is activated. By | |||
default, this prompt is the name of the virtual environment folder (VenvDir) | |||
surrounded by parentheses and followed by a single space (ie. '(.venv) '). | |||
.Example | |||
Activate.ps1 | |||
Activates the Python virtual environment that contains the Activate.ps1 script. | |||
.Example | |||
Activate.ps1 -Verbose | |||
Activates the Python virtual environment that contains the Activate.ps1 script, | |||
and shows extra information about the activation as it executes. | |||
.Example | |||
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv | |||
Activates the Python virtual environment located in the specified location. | |||
.Example | |||
Activate.ps1 -Prompt "MyPython" | |||
Activates the Python virtual environment that contains the Activate.ps1 script, | |||
and prefixes the current prompt with the specified string (surrounded in | |||
parentheses) while the virtual environment is active. | |||
#> | |||
Param( | |||
[Parameter(Mandatory = $false)] | |||
[String] | |||
$VenvDir, | |||
[Parameter(Mandatory = $false)] | |||
[String] | |||
$Prompt | |||
) | |||
<# Function declarations --------------------------------------------------- #> | |||
<# | |||
.Synopsis | |||
Remove all shell session elements added by the Activate script, including the | |||
addition of the virtual environment's Python executable from the beginning of | |||
the PATH variable. | |||
.Parameter NonDestructive | |||
If present, do not remove this function from the global namespace for the | |||
session. | |||
#> | |||
function global:deactivate ([switch]$NonDestructive) { | |||
# Revert to original values | |||
# The prior prompt: | |||
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { | |||
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt | |||
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT | |||
} | |||
# The prior PYTHONHOME: | |||
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { | |||
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME | |||
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME | |||
} | |||
# The prior PATH: | |||
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { | |||
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH | |||
Remove-Item -Path Env:_OLD_VIRTUAL_PATH | |||
} | |||
# Just remove the VIRTUAL_ENV altogether: | |||
if (Test-Path -Path Env:VIRTUAL_ENV) { | |||
Remove-Item -Path env:VIRTUAL_ENV | |||
} | |||
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: | |||
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { | |||
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force | |||
} | |||
# Leave deactivate function in the global namespace if requested: | |||
if (-not $NonDestructive) { | |||
Remove-Item -Path function:deactivate | |||
} | |||
} | |||
<# | |||
.Description | |||
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the | |||
given folder, and returns them in a map. | |||
For each line in the pyvenv.cfg file, if that line can be parsed into exactly | |||
two strings separated by `=` (with any amount of whitespace surrounding the =) | |||
then it is considered a `key = value` line. The left hand string is the key, | |||
the right hand is the value. | |||
If the value starts with a `'` or a `"` then the first and last character is | |||
stripped from the value before being captured. | |||
.Parameter ConfigDir | |||
Path to the directory that contains the `pyvenv.cfg` file. | |||
#> | |||
function Get-PyVenvConfig( | |||
[String] | |||
$ConfigDir | |||
) { | |||
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" | |||
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). | |||
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue | |||
# An empty map will be returned if no config file is found. | |||
$pyvenvConfig = @{ } | |||
if ($pyvenvConfigPath) { | |||
Write-Verbose "File exists, parse `key = value` lines" | |||
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath | |||
$pyvenvConfigContent | ForEach-Object { | |||
$keyval = $PSItem -split "\s*=\s*", 2 | |||
if ($keyval[0] -and $keyval[1]) { | |||
$val = $keyval[1] | |||
# Remove extraneous quotations around a string value. | |||
if ("'""".Contains($val.Substring(0,1))) { | |||
$val = $val.Substring(1, $val.Length - 2) | |||
} | |||
$pyvenvConfig[$keyval[0]] = $val | |||
Write-Verbose "Adding Key: '$($keyval[0])'='$val'" | |||
} | |||
} | |||
} | |||
return $pyvenvConfig | |||
} | |||
<# Begin Activate script --------------------------------------------------- #> | |||
# Determine the containing directory of this script | |||
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition | |||
$VenvExecDir = Get-Item -Path $VenvExecPath | |||
Write-Verbose "Activation script is located in path: '$VenvExecPath'" | |||
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" | |||
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" | |||
# Set values required in priority: CmdLine, ConfigFile, Default | |||
# First, get the location of the virtual environment, it might not be | |||
# VenvExecDir if specified on the command line. | |||
if ($VenvDir) { | |||
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" | |||
} else { | |||
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." | |||
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") | |||
$VenvDir = $VenvDir.Insert($VenvDir.Length, "/") | |||
Write-Verbose "VenvDir=$VenvDir" | |||
} | |||
# Next, read the `pyvenv.cfg` file to determine any required value such | |||
# as `prompt`. | |||
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir | |||
# Next, set the prompt from the command line, or the config file, or | |||
# just use the name of the virtual environment folder. | |||
if ($Prompt) { | |||
Write-Verbose "Prompt specified as argument, using '$Prompt'" | |||
} else { | |||
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" | |||
if ($pyvenvCfg -and $pyvenvCfg['prompt']) { | |||
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" | |||
$Prompt = $pyvenvCfg['prompt']; | |||
} | |||
else { | |||
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" | |||
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" | |||
$Prompt = Split-Path -Path $venvDir -Leaf | |||
} | |||
} | |||
Write-Verbose "Prompt = '$Prompt'" | |||
Write-Verbose "VenvDir='$VenvDir'" | |||
# Deactivate any currently active virtual environment, but leave the | |||
# deactivate function in place. | |||
deactivate -nondestructive | |||
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine | |||
# that there is an activated venv. | |||
$env:VIRTUAL_ENV = $VenvDir | |||
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { | |||
Write-Verbose "Setting prompt to '$Prompt'" | |||
# Set the prompt to include the env name | |||
# Make sure _OLD_VIRTUAL_PROMPT is global | |||
function global:_OLD_VIRTUAL_PROMPT { "" } | |||
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT | |||
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt | |||
function global:prompt { | |||
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " | |||
_OLD_VIRTUAL_PROMPT | |||
} | |||
} | |||
# Clear PYTHONHOME | |||
if (Test-Path -Path Env:PYTHONHOME) { | |||
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME | |||
Remove-Item -Path Env:PYTHONHOME | |||
} | |||
# Add the venv to the PATH | |||
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH | |||
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" |
@@ -0,0 +1,76 @@ | |||
# This file must be used with "source bin/activate" *from bash* | |||
# you cannot run it directly | |||
deactivate () { | |||
# reset old environment variables | |||
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then | |||
PATH="${_OLD_VIRTUAL_PATH:-}" | |||
export PATH | |||
unset _OLD_VIRTUAL_PATH | |||
fi | |||
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then | |||
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" | |||
export PYTHONHOME | |||
unset _OLD_VIRTUAL_PYTHONHOME | |||
fi | |||
# This should detect bash and zsh, which have a hash command that must | |||
# be called to get it to forget past commands. Without forgetting | |||
# past commands the $PATH changes we made may not be respected | |||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then | |||
hash -r | |||
fi | |||
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then | |||
PS1="${_OLD_VIRTUAL_PS1:-}" | |||
export PS1 | |||
unset _OLD_VIRTUAL_PS1 | |||
fi | |||
unset VIRTUAL_ENV | |||
if [ ! "${1:-}" = "nondestructive" ] ; then | |||
# Self destruct! | |||
unset -f deactivate | |||
fi | |||
} | |||
# unset irrelevant variables | |||
deactivate nondestructive | |||
VIRTUAL_ENV="/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv" | |||
export VIRTUAL_ENV | |||
_OLD_VIRTUAL_PATH="$PATH" | |||
PATH="$VIRTUAL_ENV/bin:$PATH" | |||
export PATH | |||
# unset PYTHONHOME if set | |||
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) | |||
# could use `if (set -u; : $PYTHONHOME) ;` in bash | |||
if [ -n "${PYTHONHOME:-}" ] ; then | |||
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" | |||
unset PYTHONHOME | |||
fi | |||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then | |||
_OLD_VIRTUAL_PS1="${PS1:-}" | |||
if [ "x(venv) " != x ] ; then | |||
PS1="(venv) ${PS1:-}" | |||
else | |||
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" | |||
else | |||
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" | |||
fi | |||
fi | |||
export PS1 | |||
fi | |||
# This should detect bash and zsh, which have a hash command that must | |||
# be called to get it to forget past commands. Without forgetting | |||
# past commands the $PATH changes we made may not be respected | |||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then | |||
hash -r | |||
fi |
@@ -0,0 +1,37 @@ | |||
# This file must be used with "source bin/activate.csh" *from csh*. | |||
# You cannot run it directly. | |||
# Created by Davide Di Blasi <davidedb@gmail.com>. | |||
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com> | |||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' | |||
# Unset irrelevant variables. | |||
deactivate nondestructive | |||
setenv VIRTUAL_ENV "/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv" | |||
set _OLD_VIRTUAL_PATH="$PATH" | |||
setenv PATH "$VIRTUAL_ENV/bin:$PATH" | |||
set _OLD_VIRTUAL_PROMPT="$prompt" | |||
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then | |||
if ("venv" != "") then | |||
set env_name = "venv" | |||
else | |||
if (`basename "VIRTUAL_ENV"` == "__") then | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` | |||
else | |||
set env_name = `basename "$VIRTUAL_ENV"` | |||
endif | |||
endif | |||
set prompt = "[$env_name] $prompt" | |||
unset env_name | |||
endif | |||
alias pydoc python -m pydoc | |||
rehash |
@@ -0,0 +1,75 @@ | |||
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) | |||
# you cannot run it directly | |||
function deactivate -d "Exit virtualenv and return to normal shell environment" | |||
# reset old environment variables | |||
if test -n "$_OLD_VIRTUAL_PATH" | |||
set -gx PATH $_OLD_VIRTUAL_PATH | |||
set -e _OLD_VIRTUAL_PATH | |||
end | |||
if test -n "$_OLD_VIRTUAL_PYTHONHOME" | |||
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME | |||
set -e _OLD_VIRTUAL_PYTHONHOME | |||
end | |||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE" | |||
functions -e fish_prompt | |||
set -e _OLD_FISH_PROMPT_OVERRIDE | |||
functions -c _old_fish_prompt fish_prompt | |||
functions -e _old_fish_prompt | |||
end | |||
set -e VIRTUAL_ENV | |||
if test "$argv[1]" != "nondestructive" | |||
# Self destruct! | |||
functions -e deactivate | |||
end | |||
end | |||
# unset irrelevant variables | |||
deactivate nondestructive | |||
set -gx VIRTUAL_ENV "/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv" | |||
set -gx _OLD_VIRTUAL_PATH $PATH | |||
set -gx PATH "$VIRTUAL_ENV/bin" $PATH | |||
# unset PYTHONHOME if set | |||
if set -q PYTHONHOME | |||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME | |||
set -e PYTHONHOME | |||
end | |||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" | |||
# fish uses a function instead of an env var to generate the prompt. | |||
# save the current fish_prompt function as the function _old_fish_prompt | |||
functions -c fish_prompt _old_fish_prompt | |||
# with the original prompt function renamed, we can override with our own. | |||
function fish_prompt | |||
# Save the return status of the last command | |||
set -l old_status $status | |||
# Prompt override? | |||
if test -n "(venv) " | |||
printf "%s%s" "(venv) " (set_color normal) | |||
else | |||
# ...Otherwise, prepend env | |||
set -l _checkbase (basename "$VIRTUAL_ENV") | |||
if test $_checkbase = "__" | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) | |||
else | |||
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) | |||
end | |||
end | |||
# Restore the return status of the previous command. | |||
echo "exit $old_status" | . | |||
_old_fish_prompt | |||
end | |||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" | |||
end |
@@ -0,0 +1,10 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# -*- coding: utf-8 -*- | |||
import re | |||
import sys | |||
from django.core.management import execute_from_command_line | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit(execute_from_command_line()) |
@@ -0,0 +1,5 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
from django.core import management | |||
if __name__ == "__main__": | |||
management.execute_from_command_line() |
@@ -0,0 +1,12 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install' | |||
__requires__ = 'setuptools==40.8.0' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==40.8.0','console_scripts','easy_install-3.8' | |||
__requires__ = 'setuptools==40.8.0' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('setuptools==40.8.0', 'console_scripts', 'easy_install-3.8')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip' | |||
__requires__ = 'pip==19.0.3' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==19.0.3', 'console_scripts', 'pip')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3' | |||
__requires__ = 'pip==19.0.3' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==19.0.3', 'console_scripts', 'pip3')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==19.0.3','console_scripts','pip3.8' | |||
__requires__ = 'pip==19.0.3' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==19.0.3', 'console_scripts', 'pip3.8')() | |||
) |
@@ -0,0 +1,10 @@ | |||
#!/Users/macbookpro/Desktop/Webeng_praktikum/DjangoProjekt/news1/venv/bin/python | |||
# -*- coding: utf-8 -*- | |||
import re | |||
import sys | |||
from sqlparse.__main__ import main | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit(main()) |
@@ -0,0 +1 @@ | |||
pip |
@@ -0,0 +1,27 @@ | |||
Copyright (c) Django Software Foundation and individual contributors. | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or without modification, | |||
are permitted provided that the following conditions are met: | |||
1. Redistributions of source code must retain the above copyright notice, | |||
this list of conditions and the following disclaimer. | |||
2. Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution. | |||
3. Neither the name of Django nor the names of its contributors may be used | |||
to endorse or promote products derived from this software without | |||
specific prior written permission. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@@ -0,0 +1,84 @@ | |||
Metadata-Version: 2.1 | |||
Name: Django | |||
Version: 2.2.7 | |||
Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. | |||
Home-page: https://www.djangoproject.com/ | |||
Author: Django Software Foundation | |||
Author-email: foundation@djangoproject.com | |||
License: BSD | |||
Project-URL: Documentation, https://docs.djangoproject.com/ | |||
Project-URL: Funding, https://www.djangoproject.com/fundraising/ | |||
Project-URL: Source, https://github.com/django/django | |||
Project-URL: Tracker, https://code.djangoproject.com/ | |||
Platform: UNKNOWN | |||
Classifier: Development Status :: 5 - Production/Stable | |||
Classifier: Environment :: Web Environment | |||
Classifier: Framework :: Django | |||
Classifier: Intended Audience :: Developers | |||
Classifier: License :: OSI Approved :: BSD License | |||
Classifier: Operating System :: OS Independent | |||
Classifier: Programming Language :: Python | |||
Classifier: Programming Language :: Python :: 3 | |||
Classifier: Programming Language :: Python :: 3.5 | |||
Classifier: Programming Language :: Python :: 3.6 | |||
Classifier: Programming Language :: Python :: 3.7 | |||
Classifier: Programming Language :: Python :: 3 :: Only | |||
Classifier: Topic :: Internet :: WWW/HTTP | |||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content | |||
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI | |||
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks | |||
Classifier: Topic :: Software Development :: Libraries :: Python Modules | |||
Requires-Python: >=3.5 | |||
Requires-Dist: pytz | |||
Requires-Dist: sqlparse | |||
Provides-Extra: argon2 | |||
Requires-Dist: argon2-cffi (>=16.1.0) ; extra == 'argon2' | |||
Provides-Extra: bcrypt | |||
Requires-Dist: bcrypt ; extra == 'bcrypt' | |||
Django is a high-level Python Web framework that encourages rapid development | |||
and clean, pragmatic design. Thanks for checking it out. | |||
All documentation is in the "``docs``" directory and online at | |||
https://docs.djangoproject.com/en/stable/. If you're just getting started, | |||
here's how we recommend you read the docs: | |||
* First, read ``docs/intro/install.txt`` for instructions on installing Django. | |||
* Next, work through the tutorials in order (``docs/intro/tutorial01.txt``, | |||
``docs/intro/tutorial02.txt``, etc.). | |||
* If you want to set up an actual deployment server, read | |||
``docs/howto/deployment/index.txt`` for instructions. | |||
* You'll probably want to read through the topical guides (in ``docs/topics``) | |||
next; from there you can jump to the HOWTOs (in ``docs/howto``) for specific | |||
problems, and check out the reference (``docs/ref``) for gory details. | |||
* See ``docs/README`` for instructions on building an HTML version of the docs. | |||
Docs are updated rigorously. If you find any problems in the docs, or think | |||
they should be clarified in any way, please take 30 seconds to fill out a | |||
ticket here: https://code.djangoproject.com/newticket | |||
To get more help: | |||
* Join the ``#django`` channel on irc.freenode.net. Lots of helpful people hang | |||
out there. See https://en.wikipedia.org/wiki/Wikipedia:IRC/Tutorial if you're | |||
new to IRC. | |||
* Join the django-users mailing list, or read the archives, at | |||
https://groups.google.com/group/django-users. | |||
To contribute to Django: | |||
* Check out https://docs.djangoproject.com/en/dev/internals/contributing/ for | |||
information about getting involved. | |||
To run Django's test suite: | |||
* Follow the instructions in the "Unit tests" section of | |||
``docs/internals/contributing/writing-code/unit-tests.txt``, published online at | |||
https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/#running-the-unit-tests | |||
@@ -0,0 +1,5 @@ | |||
Wheel-Version: 1.0 | |||
Generator: bdist_wheel (0.33.1) | |||
Root-Is-Purelib: true | |||
Tag: py3-none-any | |||
@@ -0,0 +1,3 @@ | |||
[console_scripts] | |||
django-admin = django.core.management:execute_from_command_line | |||
@@ -0,0 +1 @@ | |||
django |
@@ -0,0 +1,24 @@ | |||
from django.utils.version import get_version | |||
VERSION = (2, 2, 7, 'final', 0) | |||
__version__ = get_version(VERSION) | |||
def setup(set_prefix=True): | |||
""" | |||
Configure the settings (this happens as a side effect of accessing the | |||
first setting), configure logging and populate the app registry. | |||
Set the thread-local urlresolvers script prefix if `set_prefix` is True. | |||
""" | |||
from django.apps import apps | |||
from django.conf import settings | |||
from django.urls import set_script_prefix | |||
from django.utils.log import configure_logging | |||
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING) | |||
if set_prefix: | |||
set_script_prefix( | |||
'/' if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME | |||
) | |||
apps.populate(settings.INSTALLED_APPS) |
@@ -0,0 +1,9 @@ | |||
""" | |||
Invokes django-admin when the django module is run as a script. | |||
Example: python -m django check | |||
""" | |||
from django.core import management | |||
if __name__ == "__main__": | |||
management.execute_from_command_line() |
@@ -0,0 +1,4 @@ | |||
from .config import AppConfig | |||
from .registry import apps | |||
__all__ = ['AppConfig', 'apps'] |
@@ -0,0 +1,216 @@ | |||
import os | |||
from importlib import import_module | |||
from django.core.exceptions import ImproperlyConfigured | |||
from django.utils.module_loading import module_has_submodule | |||
MODELS_MODULE_NAME = 'models' | |||
class AppConfig: | |||
"""Class representing a Django application and its configuration.""" | |||
def __init__(self, app_name, app_module): | |||
# Full Python path to the application e.g. 'django.contrib.admin'. | |||
self.name = app_name | |||
# Root module for the application e.g. <module 'django.contrib.admin' | |||
# from 'django/contrib/admin/__init__.py'>. | |||
self.module = app_module | |||
# Reference to the Apps registry that holds this AppConfig. Set by the | |||
# registry when it registers the AppConfig instance. | |||
self.apps = None | |||
# The following attributes could be defined at the class level in a | |||
# subclass, hence the test-and-set pattern. | |||
# Last component of the Python path to the application e.g. 'admin'. | |||
# This value must be unique across a Django project. | |||
if not hasattr(self, 'label'): | |||
self.label = app_name.rpartition(".")[2] | |||
# Human-readable name for the application e.g. "Admin". | |||
if not hasattr(self, 'verbose_name'): | |||
self.verbose_name = self.label.title() | |||
# Filesystem path to the application directory e.g. | |||
# '/path/to/django/contrib/admin'. | |||
if not hasattr(self, 'path'): | |||
self.path = self._path_from_module(app_module) | |||
# Module containing models e.g. <module 'django.contrib.admin.models' | |||
# from 'django/contrib/admin/models.py'>. Set by import_models(). | |||
# None if the application doesn't have a models module. | |||
self.models_module = None | |||
# Mapping of lowercase model names to model classes. Initially set to | |||
# None to prevent accidental access before import_models() runs. | |||
self.models = None | |||
def __repr__(self): | |||
return '<%s: %s>' % (self.__class__.__name__, self.label) | |||
def _path_from_module(self, module): | |||
"""Attempt to determine app's filesystem path from its module.""" | |||
# See #21874 for extended discussion of the behavior of this method in | |||
# various cases. | |||
# Convert paths to list because Python's _NamespacePath doesn't support | |||
# indexing. | |||
paths = list(getattr(module, '__path__', [])) | |||
if len(paths) != 1: | |||
filename = getattr(module, '__file__', None) | |||
if filename is not None: | |||
paths = [os.path.dirname(filename)] | |||
else: | |||
# For unknown reasons, sometimes the list returned by __path__ | |||
# contains duplicates that must be removed (#25246). | |||
paths = list(set(paths)) | |||
if len(paths) > 1: | |||
raise ImproperlyConfigured( | |||
"The app module %r has multiple filesystem locations (%r); " | |||
"you must configure this app with an AppConfig subclass " | |||
"with a 'path' class attribute." % (module, paths)) | |||
elif not paths: | |||
raise ImproperlyConfigured( | |||
"The app module %r has no filesystem location, " | |||
"you must configure this app with an AppConfig subclass " | |||
"with a 'path' class attribute." % (module,)) | |||
return paths[0] | |||
@classmethod | |||
def create(cls, entry): | |||
""" | |||
Factory that creates an app config from an entry in INSTALLED_APPS. | |||
""" | |||
try: | |||
# If import_module succeeds, entry is a path to an app module, | |||
# which may specify an app config class with default_app_config. | |||
# Otherwise, entry is a path to an app config class or an error. | |||
module = import_module(entry) | |||
except ImportError: | |||
# Track that importing as an app module failed. If importing as an | |||
# app config class fails too, we'll trigger the ImportError again. | |||
module = None | |||
mod_path, _, cls_name = entry.rpartition('.') | |||
# Raise the original exception when entry cannot be a path to an | |||
# app config class. | |||
if not mod_path: | |||
raise | |||
else: | |||
try: | |||
# If this works, the app module specifies an app config class. | |||
entry = module.default_app_config | |||
except AttributeError: | |||
# Otherwise, it simply uses the default app config class. | |||
return cls(entry, module) | |||
else: | |||
mod_path, _, cls_name = entry.rpartition('.') | |||
# If we're reaching this point, we must attempt to load the app config | |||
# class located at <mod_path>.<cls_name> | |||
mod = import_module(mod_path) | |||
try: | |||
cls = getattr(mod, cls_name) | |||
except AttributeError: | |||
if module is None: | |||
# If importing as an app module failed, check if the module | |||
# contains any valid AppConfigs and show them as choices. | |||
# Otherwise, that error probably contains the most informative | |||
# traceback, so trigger it again. | |||
candidates = sorted( | |||
repr(name) for name, candidate in mod.__dict__.items() | |||
if isinstance(candidate, type) and | |||
issubclass(candidate, AppConfig) and | |||
candidate is not AppConfig | |||
) | |||
if candidates: | |||
raise ImproperlyConfigured( | |||
"'%s' does not contain a class '%s'. Choices are: %s." | |||
% (mod_path, cls_name, ', '.join(candidates)) | |||
) | |||
import_module(entry) | |||
else: | |||
raise | |||
# Check for obvious errors. (This check prevents duck typing, but | |||
# it could be removed if it became a problem in practice.) | |||
if not issubclass(cls, AppConfig): | |||
raise ImproperlyConfigured( | |||
"'%s' isn't a subclass of AppConfig." % entry) | |||
# Obtain app name here rather than in AppClass.__init__ to keep | |||
# all error checking for entries in INSTALLED_APPS in one place. | |||
try: | |||
app_name = cls.name | |||
except AttributeError: | |||
raise ImproperlyConfigured( | |||
"'%s' must supply a name attribute." % entry) | |||
# Ensure app_name points to a valid module. | |||
try: | |||
app_module = import_module(app_name) | |||
except ImportError: | |||
raise ImproperlyConfigured( | |||
"Cannot import '%s'. Check that '%s.%s.name' is correct." % ( | |||
app_name, mod_path, cls_name, | |||
) | |||
) | |||
# Entry is a path to an app config class. | |||
return cls(app_name, app_module) | |||
def get_model(self, model_name, require_ready=True): | |||
""" | |||
Return the model with the given case-insensitive model_name. | |||
Raise LookupError if no model exists with this name. | |||
""" | |||
if require_ready: | |||
self.apps.check_models_ready() | |||
else: | |||
self.apps.check_apps_ready() | |||
try: | |||
return self.models[model_name.lower()] | |||
except KeyError: | |||
raise LookupError( | |||
"App '%s' doesn't have a '%s' model." % (self.label, model_name)) | |||
def get_models(self, include_auto_created=False, include_swapped=False): | |||
""" | |||
Return an iterable of models. | |||
By default, the following models aren't included: | |||
- auto-created models for many-to-many relations without | |||
an explicit intermediate table, | |||
- models that have been swapped out. | |||
Set the corresponding keyword argument to True to include such models. | |||
Keyword arguments aren't documented; they're a private API. | |||
""" | |||
self.apps.check_models_ready() | |||
for model in self.models.values(): | |||
if model._meta.auto_created and not include_auto_created: | |||
continue | |||
if model._meta.swapped and not include_swapped: | |||
continue | |||
yield model | |||
def import_models(self): | |||
# Dictionary of models for this app, primarily maintained in the | |||
# 'all_models' attribute of the Apps this AppConfig is attached to. | |||
self.models = self.apps.all_models[self.label] | |||
if module_has_submodule(self.module, MODELS_MODULE_NAME): | |||
models_module_name = '%s.%s' % (self.name, MODELS_MODULE_NAME) | |||
self.models_module = import_module(models_module_name) | |||
def ready(self): | |||
""" | |||
Override this method in subclasses to run code when Django starts. | |||
""" |
@@ -0,0 +1,426 @@ | |||
import functools | |||
import sys | |||
import threading | |||
import warnings | |||
from collections import Counter, OrderedDict, defaultdict | |||
from functools import partial | |||
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured | |||
from .config import AppConfig | |||
class Apps: | |||
""" | |||
A registry that stores the configuration of installed applications. | |||
It also keeps track of models, e.g. to provide reverse relations. | |||
""" | |||
def __init__(self, installed_apps=()): | |||
# installed_apps is set to None when creating the master registry | |||
# because it cannot be populated at that point. Other registries must | |||
# provide a list of installed apps and are populated immediately. | |||
if installed_apps is None and hasattr(sys.modules[__name__], 'apps'): | |||
raise RuntimeError("You must supply an installed_apps argument.") | |||
# Mapping of app labels => model names => model classes. Every time a | |||
# model is imported, ModelBase.__new__ calls apps.register_model which | |||
# creates an entry in all_models. All imported models are registered, | |||
# regardless of whether they're defined in an installed application | |||
# and whether the registry has been populated. Since it isn't possible | |||
# to reimport a module safely (it could reexecute initialization code) | |||
# all_models is never overridden or reset. | |||
self.all_models = defaultdict(OrderedDict) | |||
# Mapping of labels to AppConfig instances for installed apps. | |||
self.app_configs = OrderedDict() | |||
# Stack of app_configs. Used to store the current state in | |||
# set_available_apps and set_installed_apps. | |||
self.stored_app_configs = [] | |||
# Whether the registry is populated. | |||
self.apps_ready = self.models_ready = self.ready = False | |||
# For the autoreloader. | |||
self.ready_event = threading.Event() | |||
# Lock for thread-safe population. | |||
self._lock = threading.RLock() | |||
self.loading = False | |||
# Maps ("app_label", "modelname") tuples to lists of functions to be | |||
# called when the corresponding model is ready. Used by this class's | |||
# `lazy_model_operation()` and `do_pending_operations()` methods. | |||
self._pending_operations = defaultdict(list) | |||
# Populate apps and models, unless it's the master registry. | |||
if installed_apps is not None: | |||
self.populate(installed_apps) | |||
def populate(self, installed_apps=None): | |||
""" | |||
Load application configurations and models. | |||
Import each application module and then each model module. | |||
It is thread-safe and idempotent, but not reentrant. | |||
""" | |||
if self.ready: | |||
return | |||
# populate() might be called by two threads in parallel on servers | |||
# that create threads before initializing the WSGI callable. | |||
with self._lock: | |||
if self.ready: | |||
return | |||
# An RLock prevents other threads from entering this section. The | |||
# compare and set operation below is atomic. | |||
if self.loading: | |||
# Prevent reentrant calls to avoid running AppConfig.ready() | |||
# methods twice. | |||
raise RuntimeError("populate() isn't reentrant") | |||
self.loading = True | |||
# Phase 1: initialize app configs and import app modules. | |||
for entry in installed_apps: | |||
if isinstance(entry, AppConfig): | |||
app_config = entry | |||
else: | |||
app_config = AppConfig.create(entry) | |||
if app_config.label in self.app_configs: | |||
raise ImproperlyConfigured( | |||
"Application labels aren't unique, " | |||
"duplicates: %s" % app_config.label) | |||
self.app_configs[app_config.label] = app_config | |||
app_config.apps = self | |||
# Check for duplicate app names. | |||
counts = Counter( | |||
app_config.name for app_config in self.app_configs.values()) | |||
duplicates = [ | |||
name for name, count in counts.most_common() if count > 1] | |||
if duplicates: | |||
raise ImproperlyConfigured( | |||
"Application names aren't unique, " | |||
"duplicates: %s" % ", ".join(duplicates)) | |||
self.apps_ready = True | |||
# Phase 2: import models modules. | |||
for app_config in self.app_configs.values(): | |||
app_config.import_models() | |||
self.clear_cache() | |||
self.models_ready = True | |||
# Phase 3: run ready() methods of app configs. | |||
for app_config in self.get_app_configs(): | |||
app_config.ready() | |||
self.ready = True | |||
self.ready_event.set() | |||
def check_apps_ready(self): | |||
"""Raise an exception if all apps haven't been imported yet.""" | |||
if not self.apps_ready: | |||
from django.conf import settings | |||
# If "not ready" is due to unconfigured settings, accessing | |||
# INSTALLED_APPS raises a more helpful ImproperlyConfigured | |||
# exception. | |||
settings.INSTALLED_APPS | |||
raise AppRegistryNotReady("Apps aren't loaded yet.") | |||
def check_models_ready(self): | |||
"""Raise an exception if all models haven't been imported yet.""" | |||
if not self.models_ready: | |||
raise AppRegistryNotReady("Models aren't loaded yet.") | |||
def get_app_configs(self): | |||
"""Import applications and return an iterable of app configs.""" | |||
self.check_apps_ready() | |||
return self.app_configs.values() | |||
def get_app_config(self, app_label): | |||
""" | |||
Import applications and returns an app config for the given label. | |||
Raise LookupError if no application exists with this label. | |||
""" | |||
self.check_apps_ready() | |||
try: | |||
return self.app_configs[app_label] | |||
except KeyError: | |||
message = "No installed app with label '%s'." % app_label | |||
for app_config in self.get_app_configs(): | |||
if app_config.name == app_label: | |||
message += " Did you mean '%s'?" % app_config.label | |||
break | |||
raise LookupError(message) | |||
# This method is performance-critical at least for Django's test suite. | |||
@functools.lru_cache(maxsize=None) | |||
def get_models(self, include_auto_created=False, include_swapped=False): | |||
""" | |||
Return a list of all installed models. | |||
By default, the following models aren't included: | |||
- auto-created models for many-to-many relations without | |||
an explicit intermediate table, | |||
- models that have been swapped out. | |||
Set the corresponding keyword argument to True to include such models. | |||
""" | |||
self.check_models_ready() | |||
result = [] | |||
for app_config in self.app_configs.values(): | |||
result.extend(app_config.get_models(include_auto_created, include_swapped)) | |||
return result | |||
def get_model(self, app_label, model_name=None, require_ready=True): | |||
""" | |||
Return the model matching the given app_label and model_name. | |||
As a shortcut, app_label may be in the form <app_label>.<model_name>. | |||
model_name is case-insensitive. | |||
Raise LookupError if no application exists with this label, or no | |||
model exists with this name in the application. Raise ValueError if | |||
called with a single argument that doesn't contain exactly one dot. | |||
""" | |||
if require_ready: | |||
self.check_models_ready() | |||
else: | |||
self.check_apps_ready() | |||
if model_name is None: | |||
app_label, model_name = app_label.split('.') | |||
app_config = self.get_app_config(app_label) | |||
if not require_ready and app_config.models is None: | |||
app_config.import_models() | |||
return app_config.get_model(model_name, require_ready=require_ready) | |||
def register_model(self, app_label, model): | |||
# Since this method is called when models are imported, it cannot | |||
# perform imports because of the risk of import loops. It mustn't | |||
# call get_app_config(). | |||
model_name = model._meta.model_name | |||
app_models = self.all_models[app_label] | |||
if model_name in app_models: | |||
if (model.__name__ == app_models[model_name].__name__ and | |||
model.__module__ == app_models[model_name].__module__): | |||
warnings.warn( | |||
"Model '%s.%s' was already registered. " | |||
"Reloading models is not advised as it can lead to inconsistencies, " | |||
"most notably with related models." % (app_label, model_name), | |||
RuntimeWarning, stacklevel=2) | |||
else: | |||
raise RuntimeError( | |||
"Conflicting '%s' models in application '%s': %s and %s." % | |||
(model_name, app_label, app_models[model_name], model)) | |||
app_models[model_name] = model | |||
self.do_pending_operations(model) | |||
self.clear_cache() | |||
def is_installed(self, app_name): | |||
""" | |||
Check whether an application with this name exists in the registry. | |||
app_name is the full name of the app e.g. 'django.contrib.admin'. | |||
""" | |||
self.check_apps_ready() | |||
return any(ac.name == app_name for ac in self.app_configs.values()) | |||
def get_containing_app_config(self, object_name): | |||
""" | |||
Look for an app config containing a given object. | |||
object_name is the dotted Python path to the object. | |||
Return the app config for the inner application in case of nesting. | |||
Return None if the object isn't in any registered app config. | |||
""" | |||
self.check_apps_ready() | |||
candidates = [] | |||
for app_config in self.app_configs.values(): | |||
if object_name.startswith(app_config.name): | |||
subpath = object_name[len(app_config.name):] | |||
if subpath == '' or subpath[0] == '.': | |||
candidates.append(app_config) | |||
if candidates: | |||
return sorted(candidates, key=lambda ac: -len(ac.name))[0] | |||
def get_registered_model(self, app_label, model_name): | |||
""" | |||
Similar to get_model(), but doesn't require that an app exists with | |||
the given app_label. | |||
It's safe to call this method at import time, even while the registry | |||
is being populated. | |||
""" | |||
model = self.all_models[app_label].get(model_name.lower()) | |||
if model is None: | |||
raise LookupError( | |||
"Model '%s.%s' not registered." % (app_label, model_name)) | |||
return model | |||
@functools.lru_cache(maxsize=None) | |||
def get_swappable_settings_name(self, to_string): | |||
""" | |||
For a given model string (e.g. "auth.User"), return the name of the | |||
corresponding settings name if it refers to a swappable model. If the | |||
referred model is not swappable, return None. | |||
This method is decorated with lru_cache because it's performance | |||
critical when it comes to migrations. Since the swappable settings don't | |||
change after Django has loaded the settings, there is no reason to get | |||
the respective settings attribute over and over again. | |||
""" | |||
for model in self.get_models(include_swapped=True): | |||
swapped = model._meta.swapped | |||
# Is this model swapped out for the model given by to_string? | |||
if swapped and swapped == to_string: | |||
return model._meta.swappable | |||
# Is this model swappable and the one given by to_string? | |||
if model._meta.swappable and model._meta.label == to_string: | |||
return model._meta.swappable | |||
return None | |||
def set_available_apps(self, available): | |||
""" | |||
Restrict the set of installed apps used by get_app_config[s]. | |||
available must be an iterable of application names. | |||
set_available_apps() must be balanced with unset_available_apps(). | |||
Primarily used for performance optimization in TransactionTestCase. | |||
This method is safe in the sense that it doesn't trigger any imports. | |||
""" | |||
available = set(available) | |||
installed = {app_config.name for app_config in self.get_app_configs()} | |||
if not available.issubset(installed): | |||
raise ValueError( | |||
"Available apps isn't a subset of installed apps, extra apps: %s" | |||
% ", ".join(available - installed) | |||
) | |||
self.stored_app_configs.append(self.app_configs) | |||
self.app_configs = OrderedDict( | |||
(label, app_config) | |||
for label, app_config in self.app_configs.items() | |||
if app_config.name in available) | |||
self.clear_cache() | |||
def unset_available_apps(self): | |||
"""Cancel a previous call to set_available_apps().""" | |||
self.app_configs = self.stored_app_configs.pop() | |||
self.clear_cache() | |||
def set_installed_apps(self, installed): | |||
""" | |||
Enable a different set of installed apps for get_app_config[s]. | |||
installed must be an iterable in the same format as INSTALLED_APPS. | |||
set_installed_apps() must be balanced with unset_installed_apps(), | |||
even if it exits with an exception. | |||
Primarily used as a receiver of the setting_changed signal in tests. | |||
This method may trigger new imports, which may add new models to the | |||
registry of all imported models. They will stay in the registry even | |||
after unset_installed_apps(). Since it isn't possible to replay | |||
imports safely (e.g. that could lead to registering listeners twice), | |||
models are registered when they're imported and never removed. | |||
""" | |||
if not self.ready: | |||
raise AppRegistryNotReady("App registry isn't ready yet.") | |||
self.stored_app_configs.append(self.app_configs) | |||
self.app_configs = OrderedDict() | |||
self.apps_ready = self.models_ready = self.loading = self.ready = False | |||
self.clear_cache() | |||
self.populate(installed) | |||
def unset_installed_apps(self): | |||
"""Cancel a previous call to set_installed_apps().""" | |||
self.app_configs = self.stored_app_configs.pop() | |||
self.apps_ready = self.models_ready = self.ready = True | |||
self.clear_cache() | |||
def clear_cache(self): | |||
""" | |||
Clear all internal caches, for methods that alter the app registry. | |||
This is mostly used in tests. | |||
""" | |||
# Call expire cache on each model. This will purge | |||
# the relation tree and the fields cache. | |||
self.get_models.cache_clear() | |||
if self.ready: | |||
# Circumvent self.get_models() to prevent that the cache is refilled. | |||
# This particularly prevents that an empty value is cached while cloning. | |||
for app_config in self.app_configs.values(): | |||
for model in app_config.get_models(include_auto_created=True): | |||
model._meta._expire_cache() | |||
def lazy_model_operation(self, function, *model_keys): | |||
""" | |||
Take a function and a number of ("app_label", "modelname") tuples, and | |||
when all the corresponding models have been imported and registered, | |||
call the function with the model classes as its arguments. | |||
The function passed to this method must accept exactly n models as | |||
arguments, where n=len(model_keys). | |||
""" | |||
# Base case: no arguments, just execute the function. | |||
if not model_keys: | |||
function() | |||
# Recursive case: take the head of model_keys, wait for the | |||
# corresponding model class to be imported and registered, then apply | |||
# that argument to the supplied function. Pass the resulting partial | |||
# to lazy_model_operation() along with the remaining model args and | |||
# repeat until all models are loaded and all arguments are applied. | |||
else: | |||
next_model, *more_models = model_keys | |||
# This will be executed after the class corresponding to next_model | |||
# has been imported and registered. The `func` attribute provides | |||
# duck-type compatibility with partials. | |||
def apply_next_model(model): | |||
next_function = partial(apply_next_model.func, model) | |||
self.lazy_model_operation(next_function, *more_models) | |||
apply_next_model.func = function | |||
# If the model has already been imported and registered, partially | |||
# apply it to the function now. If not, add it to the list of | |||
# pending operations for the model, where it will be executed with | |||
# the model class as its sole argument once the model is ready. | |||
try: | |||
model_class = self.get_registered_model(*next_model) | |||
except LookupError: | |||
self._pending_operations[next_model].append(apply_next_model) | |||
else: | |||
apply_next_model(model_class) | |||
def do_pending_operations(self, model): | |||
""" | |||
Take a newly-prepared model and pass it to each function waiting for | |||
it. This is called at the very end of Apps.register_model(). | |||
""" | |||
key = model._meta.app_label, model._meta.model_name | |||
for function in self._pending_operations.pop(key, []): | |||
function(model) | |||
apps = Apps(installed_apps=None) |
@@ -0,0 +1,5 @@ | |||
#!/usr/bin/env python | |||
from django.core import management | |||
if __name__ == "__main__": | |||
management.execute_from_command_line() |
@@ -0,0 +1,255 @@ | |||
""" | |||
Settings and configuration for Django. | |||
Read values from the module specified by the DJANGO_SETTINGS_MODULE environment | |||
variable, and then from django.conf.global_settings; see the global_settings.py | |||
for a list of all possible variables. | |||
""" | |||
import importlib | |||
import os | |||
import time | |||
import traceback | |||
import warnings | |||
from pathlib import Path | |||
import django | |||
from django.conf import global_settings | |||
from django.core.exceptions import ImproperlyConfigured | |||
from django.utils.deprecation import ( | |||
RemovedInDjango30Warning, RemovedInDjango31Warning, | |||
) | |||
from django.utils.functional import LazyObject, empty | |||
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" | |||
DEFAULT_CONTENT_TYPE_DEPRECATED_MSG = 'The DEFAULT_CONTENT_TYPE setting is deprecated.' | |||
FILE_CHARSET_DEPRECATED_MSG = ( | |||
'The FILE_CHARSET setting is deprecated. Starting with Django 3.1, all ' | |||
'files read from disk must be UTF-8 encoded.' | |||
) | |||
class SettingsReference(str): | |||
""" | |||
String subclass which references a current settings value. It's treated as | |||
the value in memory but serializes to a settings.NAME attribute reference. | |||
""" | |||
def __new__(self, value, setting_name): | |||
return str.__new__(self, value) | |||
def __init__(self, value, setting_name): | |||
self.setting_name = setting_name | |||
class LazySettings(LazyObject): | |||
""" | |||
A lazy proxy for either global Django settings or a custom settings object. | |||
The user can manually configure settings prior to using them. Otherwise, | |||
Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE. | |||
""" | |||
def _setup(self, name=None): | |||
""" | |||
Load the settings module pointed to by the environment variable. This | |||
is used the first time settings are needed, if the user hasn't | |||
configured settings manually. | |||
""" | |||
settings_module = os.environ.get(ENVIRONMENT_VARIABLE) | |||
if not settings_module: | |||
desc = ("setting %s" % name) if name else "settings" | |||
raise ImproperlyConfigured( | |||
"Requested %s, but settings are not configured. " | |||
"You must either define the environment variable %s " | |||
"or call settings.configure() before accessing settings." | |||
% (desc, ENVIRONMENT_VARIABLE)) | |||
self._wrapped = Settings(settings_module) | |||
def __repr__(self): | |||
# Hardcode the class name as otherwise it yields 'Settings'. | |||
if self._wrapped is empty: | |||
return '<LazySettings [Unevaluated]>' | |||
return '<LazySettings "%(settings_module)s">' % { | |||
'settings_module': self._wrapped.SETTINGS_MODULE, | |||
} | |||
def __getattr__(self, name): | |||
"""Return the value of a setting and cache it in self.__dict__.""" | |||
if self._wrapped is empty: | |||
self._setup(name) | |||
val = getattr(self._wrapped, name) | |||
self.__dict__[name] = val | |||
return val | |||
def __setattr__(self, name, value): | |||
""" | |||
Set the value of setting. Clear all cached values if _wrapped changes | |||
(@override_settings does this) or clear single values when set. | |||
""" | |||
if name == '_wrapped': | |||
self.__dict__.clear() | |||
else: | |||
self.__dict__.pop(name, None) | |||
super().__setattr__(name, value) | |||
def __delattr__(self, name): | |||
"""Delete a setting and clear it from cache if needed.""" | |||
super().__delattr__(name) | |||
self.__dict__.pop(name, None) | |||
def configure(self, default_settings=global_settings, **options): | |||
""" | |||
Called to manually configure the settings. The 'default_settings' | |||
parameter sets where to retrieve any unspecified values from (its | |||
argument must support attribute access (__getattr__)). | |||
""" | |||
if self._wrapped is not empty: | |||
raise RuntimeError('Settings already configured.') | |||
holder = UserSettingsHolder(default_settings) | |||
for name, value in options.items(): | |||
setattr(holder, name, value) | |||
self._wrapped = holder | |||
@property | |||
def configured(self): | |||
"""Return True if the settings have already been configured.""" | |||
return self._wrapped is not empty | |||
@property | |||
def DEFAULT_CONTENT_TYPE(self): | |||
stack = traceback.extract_stack() | |||
# Show a warning if the setting is used outside of Django. | |||
# Stack index: -1 this line, -2 the caller. | |||
filename, _line_number, _function_name, _text = stack[-2] | |||
if not filename.startswith(os.path.dirname(django.__file__)): | |||
warnings.warn( | |||
DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, | |||
RemovedInDjango30Warning, | |||
stacklevel=2, | |||
) | |||
return self.__getattr__('DEFAULT_CONTENT_TYPE') | |||
@property | |||
def FILE_CHARSET(self): | |||
stack = traceback.extract_stack() | |||
# Show a warning if the setting is used outside of Django. | |||
# Stack index: -1 this line, -2 the caller. | |||
filename, _line_number, _function_name, _text = stack[-2] | |||
if not filename.startswith(os.path.dirname(django.__file__)): | |||
warnings.warn( | |||
FILE_CHARSET_DEPRECATED_MSG, | |||
RemovedInDjango31Warning, | |||
stacklevel=2, | |||
) | |||
return self.__getattr__('FILE_CHARSET') | |||
class Settings: | |||
def __init__(self, settings_module): | |||
# update this dict from global settings (but only for ALL_CAPS settings) | |||
for setting in dir(global_settings): | |||
if setting.isupper(): | |||
setattr(self, setting, getattr(global_settings, setting)) | |||
# store the settings module in case someone later cares | |||
self.SETTINGS_MODULE = settings_module | |||
mod = importlib.import_module(self.SETTINGS_MODULE) | |||
tuple_settings = ( | |||
"INSTALLED_APPS", | |||
"TEMPLATE_DIRS", | |||
"LOCALE_PATHS", | |||
) | |||
self._explicit_settings = set() | |||
for setting in dir(mod): | |||
if setting.isupper(): | |||
setting_value = getattr(mod, setting) | |||
if (setting in tuple_settings and | |||
not isinstance(setting_value, (list, tuple))): | |||
raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting) | |||
setattr(self, setting, setting_value) | |||
self._explicit_settings.add(setting) | |||
if not self.SECRET_KEY: | |||
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") | |||
if self.is_overridden('DEFAULT_CONTENT_TYPE'): | |||
warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning) | |||
if self.is_overridden('FILE_CHARSET'): | |||
warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning) | |||
if hasattr(time, 'tzset') and self.TIME_ZONE: | |||
# When we can, attempt to validate the timezone. If we can't find | |||
# this file, no check happens and it's harmless. | |||
zoneinfo_root = Path('/usr/share/zoneinfo') | |||
zone_info_file = zoneinfo_root.joinpath(*self.TIME_ZONE.split('/')) | |||
if zoneinfo_root.exists() and not zone_info_file.exists(): | |||
raise ValueError("Incorrect timezone setting: %s" % self.TIME_ZONE) | |||
# Move the time zone info into os.environ. See ticket #2315 for why | |||
# we don't do this unconditionally (breaks Windows). | |||
os.environ['TZ'] = self.TIME_ZONE | |||
time.tzset() | |||
def is_overridden(self, setting): | |||
return setting in self._explicit_settings | |||
def __repr__(self): | |||
return '<%(cls)s "%(settings_module)s">' % { | |||
'cls': self.__class__.__name__, | |||
'settings_module': self.SETTINGS_MODULE, | |||
} | |||
class UserSettingsHolder: | |||
"""Holder for user configured settings.""" | |||
# SETTINGS_MODULE doesn't make much sense in the manually configured | |||
# (standalone) case. | |||
SETTINGS_MODULE = None | |||
def __init__(self, default_settings): | |||
""" | |||
Requests for configuration variables not in this class are satisfied | |||
from the module specified in default_settings (if possible). | |||
""" | |||
self.__dict__['_deleted'] = set() | |||
self.default_settings = default_settings | |||
def __getattr__(self, name): | |||
if name in self._deleted: | |||
raise AttributeError | |||
return getattr(self.default_settings, name) | |||
def __setattr__(self, name, value): | |||
self._deleted.discard(name) | |||
if name == 'DEFAULT_CONTENT_TYPE': | |||
warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning) | |||
elif name == 'FILE_CHARSET': | |||
warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning) | |||
super().__setattr__(name, value) | |||
def __delattr__(self, name): | |||
self._deleted.add(name) | |||
if hasattr(self, name): | |||
super().__delattr__(name) | |||
def __dir__(self): | |||
return sorted( | |||
s for s in [*self.__dict__, *dir(self.default_settings)] | |||
if s not in self._deleted | |||
) | |||
def is_overridden(self, setting): | |||
deleted = (setting in self._deleted) | |||
set_locally = (setting in self.__dict__) | |||
set_on_default = getattr(self.default_settings, 'is_overridden', lambda s: False)(setting) | |||
return deleted or set_locally or set_on_default | |||
def __repr__(self): | |||
return '<%(cls)s>' % { | |||
'cls': self.__class__.__name__, | |||
} | |||
settings = LazySettings() |
@@ -0,0 +1,3 @@ | |||
from django.contrib import admin | |||
# Register your models here. |
@@ -0,0 +1,5 @@ | |||
from django.apps import AppConfig | |||
class {{ camel_case_app_name }}Config(AppConfig): | |||
name = '{{ app_name }}' |
@@ -0,0 +1,3 @@ | |||
from django.db import models | |||
# Create your models here. |
@@ -0,0 +1,3 @@ | |||
from django.test import TestCase | |||
# Create your tests here. |
@@ -0,0 +1,3 @@ | |||
from django.shortcuts import render | |||
# Create your views here. |
@@ -0,0 +1,636 @@ | |||
""" | |||
Default Django settings. Override these with settings in the module pointed to | |||
by the DJANGO_SETTINGS_MODULE environment variable. | |||
""" | |||
# This is defined here as a do-nothing function because we can't import | |||
# django.utils.translation -- that module depends on the settings. | |||
def gettext_noop(s): | |||
return s | |||
#################### | |||
# CORE # | |||
#################### | |||
DEBUG = False | |||
# Whether the framework should propagate raw exceptions rather than catching | |||
# them. This is useful under some testing situations and should never be used | |||