generated from 2martens/django-template
Initial commit
This commit is contained in:
commit
85d5f0b123
|
@ -0,0 +1,240 @@
|
||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# ---> Node
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
Apache License
|
||||||
|
|
||||||
|
Version 2.0, January 2004
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
|
||||||
|
AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and distribution
|
||||||
|
as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct
|
||||||
|
or indirect, to cause the direction or management of such entity, whether
|
||||||
|
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
|
||||||
|
of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
|
||||||
|
granted by this License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation
|
||||||
|
or translation of a Source form, including but not limited to compiled object
|
||||||
|
code, generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form,
|
||||||
|
made available under the License, as indicated by a copyright notice that
|
||||||
|
is included in or attached to the work (an example is provided in the Appendix
|
||||||
|
below).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form,
|
||||||
|
that is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative
|
||||||
|
Works shall not include works that remain separable from, or merely link (or
|
||||||
|
bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative
|
||||||
|
Works thereof, that is intentionally submitted to Licensor for inclusion in
|
||||||
|
the Work by the copyright owner or by an individual or Legal Entity authorized
|
||||||
|
to submit on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication
|
||||||
|
sent to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor
|
||||||
|
for the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently incorporated
|
||||||
|
within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||||
|
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||||
|
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
|
||||||
|
the Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
||||||
|
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||||
|
license to make, have made, use, offer to sell, sell, import, and otherwise
|
||||||
|
transfer the Work, where such license applies only to those patent claims
|
||||||
|
licensable by such Contributor that are necessarily infringed by their Contribution(s)
|
||||||
|
alone or by combination of their Contribution(s) with the Work to which such
|
||||||
|
Contribution(s) was submitted. If You institute patent litigation against
|
||||||
|
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that the Work or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses granted to You
|
||||||
|
under this License for that Work shall terminate as of the date such litigation
|
||||||
|
is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||||
|
Derivative Works thereof in any medium, with or without modifications, and
|
||||||
|
in Source or Object form, provided that You meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or Derivative Works a copy
|
||||||
|
of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices stating that
|
||||||
|
You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source
|
||||||
|
form of the Work, excluding those notices that do not pertain to any part
|
||||||
|
of the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its distribution,
|
||||||
|
then any Derivative Works that You distribute must include a readable copy
|
||||||
|
of the attribution notices contained within such NOTICE file, excluding those
|
||||||
|
notices that do not pertain to any part of the Derivative Works, in at least
|
||||||
|
one of the following places: within a NOTICE text file distributed as part
|
||||||
|
of the Derivative Works; within the Source form or documentation, if provided
|
||||||
|
along with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works
|
||||||
|
that You distribute, alongside or as an addendum to the NOTICE text from the
|
||||||
|
Work, provided that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction,
|
||||||
|
or distribution of Your modifications, or for any such Derivative Works as
|
||||||
|
a whole, provided Your use, reproduction, and distribution of the Work otherwise
|
||||||
|
complies with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||||
|
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||||
|
Licensor shall be under the terms and conditions of this License, without
|
||||||
|
any additional terms or conditions. Notwithstanding the above, nothing herein
|
||||||
|
shall supersede or modify the terms of any separate license agreement you
|
||||||
|
may have executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or product names of the Licensor, except as required
|
||||||
|
for reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
|
||||||
|
in writing, Licensor provides the Work (and each Contributor provides its
|
||||||
|
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied, including, without limitation, any warranties
|
||||||
|
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
|
||||||
|
of using or redistributing the Work and assume any risks associated with Your
|
||||||
|
exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, whether
|
||||||
|
in tort (including negligence), contract, or otherwise, unless required by
|
||||||
|
applicable law (such as deliberate and grossly negligent acts) or agreed to
|
||||||
|
in writing, shall any Contributor be liable to You for damages, including
|
||||||
|
any direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character arising as a result of this License or out of the use or inability
|
||||||
|
to use the Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all other commercial
|
||||||
|
damages or losses), even if such Contributor has been advised of the possibility
|
||||||
|
of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing the Work
|
||||||
|
or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||||
|
acceptance of support, warranty, indemnity, or other liability obligations
|
||||||
|
and/or rights consistent with this License. However, in accepting such obligations,
|
||||||
|
You may act only on Your own behalf and on Your sole responsibility, not on
|
||||||
|
behalf of any other Contributor, and only if You agree to indemnify, defend,
|
||||||
|
and hold each Contributor harmless for any liability incurred by, or claims
|
||||||
|
asserted against, such Contributor by reason of your accepting any such warranty
|
||||||
|
or additional liability. END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
information. (Don't include the brackets!) The text should be enclosed in
|
||||||
|
the appropriate comment syntax for the file format. We also recommend that
|
||||||
|
a file or class name and description of purpose be included on the same "printed
|
||||||
|
page" as the copyright notice for easier identification within third-party
|
||||||
|
archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Django template
|
||||||
|
|
||||||
|
Template repository for Django applications
|
||||||
|
|
||||||
|
## ToDos
|
||||||
|
|
||||||
|
- change ``app``into something more appropriate wherever you find it
|
||||||
|
- change ``Django template`` and ``DjangoTemplate`` into something more appropriate wherever you find it
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# coding=utf-8
|
||||||
|
default_app_config = 'chaos_dating.apps.ChaosDatingConfig'
|
|
@ -0,0 +1,39 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.contrib.auth import views as auth_views
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from chaos_dating import views as chaos_views
|
||||||
|
|
||||||
|
extra_context = {
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('login/', chaos_views.user_login, name='login'),
|
||||||
|
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
|
||||||
|
|
||||||
|
path('register/', chaos_views.register, name='register'),
|
||||||
|
|
||||||
|
path('password_change/',
|
||||||
|
auth_views.PasswordChangeView.as_view(extra_context=extra_context),
|
||||||
|
name='password_change'),
|
||||||
|
path('password_change/done/',
|
||||||
|
chaos_views.password_change_done,
|
||||||
|
name='password_change_done'),
|
||||||
|
|
||||||
|
path('password_reset/',
|
||||||
|
auth_views.PasswordResetView.as_view(extra_context=extra_context),
|
||||||
|
name='password_reset'),
|
||||||
|
path('password_reset/done/',
|
||||||
|
auth_views.PasswordResetDoneView.as_view(extra_context=extra_context),
|
||||||
|
name='password_reset_done'),
|
||||||
|
path('reset/<uidb64>/<token>/',
|
||||||
|
auth_views.PasswordResetConfirmView.as_view(extra_context=extra_context),
|
||||||
|
name='password_reset_confirm'),
|
||||||
|
path('reset/done/',
|
||||||
|
auth_views.PasswordResetCompleteView.as_view(extra_context=extra_context),
|
||||||
|
name='password_reset_complete'),
|
||||||
|
path('edit_profile/', chaos_views.edit_profile, name='edit_profile'),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
from app.models import Profile
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
|
admin.site.unregister(User)
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileInline(admin.StackedInline):
|
||||||
|
model = Profile
|
||||||
|
|
||||||
|
|
||||||
|
class UserProfileAdmin(UserAdmin):
|
||||||
|
inlines = [ProfileInline, ]
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(User, UserProfileAdmin)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class DjangoTemplateConfig(AppConfig):
|
||||||
|
name = 'app'
|
||||||
|
verbose_name = 'Django template app'
|
|
@ -0,0 +1,44 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import ReadOnlyPasswordHashField
|
||||||
|
from django.contrib.auth.forms import UsernameField
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from app.models import Profile
|
||||||
|
|
||||||
|
|
||||||
|
class UserForm(forms.ModelForm):
|
||||||
|
password = ReadOnlyPasswordHashField(
|
||||||
|
label=_("Password"),
|
||||||
|
help_text=_(
|
||||||
|
'Raw passwords are not stored, so there is no way to see the '
|
||||||
|
'password, but you can change the password using '
|
||||||
|
'<a href="{}">this form</a>.'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ['username', 'password', 'email', 'first_name', 'last_name']
|
||||||
|
field_classes = {'username': UsernameField}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
password = self.fields.get('password')
|
||||||
|
if password:
|
||||||
|
password.help_text = password.help_text.format(reverse('password_change'))
|
||||||
|
|
||||||
|
def clean_password(self):
|
||||||
|
# Regardless of what the user provides, return the initial value.
|
||||||
|
# This is done here, rather than on the field, because the
|
||||||
|
# field does not have access to the initial value
|
||||||
|
return self.initial.get('password')
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Profile
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
# coding=utf-8
|
|
@ -0,0 +1,11 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Profile(models.Model):
|
||||||
|
user = models.OneToOneField(User, models.CASCADE)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user.username
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<nav id="mainNavbar" class="navbar navbar-expand-lg navbar-light fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{% url "chaos_dating:index" %}">
|
||||||
|
<span class="fal fa-comment-alt-dots d-inline-block align-top"></span>
|
||||||
|
{{ site.title }}
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav mr-auto">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<li class="nav-item{% if active == "edit_profile" %} active{% endif %}">
|
||||||
|
<a class="nav-link" href="{% url "edit_profile" %}">
|
||||||
|
{% trans "Edit Profile" %}{% if active == "edit_profile" %}
|
||||||
|
<span class="sr-only">(current)</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url "logout" %}">
|
||||||
|
{% trans "Logout" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="nav-item{% if active == "login" %} active{% endif %}">
|
||||||
|
<a class="nav-link" href="{% url "login" %}">
|
||||||
|
{% trans "Login" %}{% if active == "login" %}
|
||||||
|
<span class="sr-only">(current)</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}
|
||||||
|
<div class="col">
|
||||||
|
<nav>
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url "chaos_dating:legal" %}">{% trans "Legal Notice" %}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url "chaos_dating:privacy" %}">{% trans "Privacy Policy" %}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {% trans "Home" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans "Home" %}</h1>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ site.title }}</h1>
|
||||||
|
|
||||||
|
<h2>{% trans "Everything else is crap" %}</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
Lorem ipsum
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>{% trans "Our radical new approach" %}</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
Lorem ipsum
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
Lorem ipsum
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
Lorem ipsum
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a class="btn btn-primary" href="{% url "register" %}">{% trans "Join the community" %}</a>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,48 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {% trans "Legal Notice" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>FIXME</h1>
|
||||||
|
<h1>{% trans "Legal Notice" %}</h1>
|
||||||
|
{% blocktrans %}
|
||||||
|
<h2>Information provided according to Sec. 5 German Telemedia Act (TMG):</h2>
|
||||||
|
<p>Jim Richard Martens<br />
|
||||||
|
Bindfeldweg 47d<br />
|
||||||
|
22459 Hamburg</p>
|
||||||
|
|
||||||
|
<h2>Contact:</h2>
|
||||||
|
<p>Email: admin@2martens.de</p>
|
||||||
|
|
||||||
|
<h2>Responsible for contents acc. to Sec. 55, para. 2 German Federal Broadcasting Agreement (RstV):</h2>
|
||||||
|
<p>Jim Martens<br />
|
||||||
|
Bindfeldweg 47d<br />
|
||||||
|
22459 Hamburg</p>
|
||||||
|
|
||||||
|
<h2>Liability for Contents</h2>
|
||||||
|
<p>As service providers, we are liable for own contents of these websites according to Sec. 7, paragraph 1 German
|
||||||
|
Telemedia Act (TMG). However, according to Sec. 8 to 10 German Telemedia Act (TMG), service providers are not
|
||||||
|
obligated to permanently monitor submitted or stored information or to search for evidences that indicate illegal
|
||||||
|
activities.</p> <p>Legal obligations to removing information or to blocking the use of information remain unchallenged.
|
||||||
|
In this case, liability is only possible at the time of knowledge about a specific violation of law. Illegal contents
|
||||||
|
will be removed immediately at the time we get knowledge of them.</p>
|
||||||
|
<h2>Liability for Links</h2>
|
||||||
|
<p>Our offer includes links to external third party websites. We have no influence on the contents of those websites,
|
||||||
|
therefore we cannot guarantee for those contents. Providers or administrators of linked websites are always responsible
|
||||||
|
for their own contents.</p>
|
||||||
|
<p>The linked websites had been checked for possible violations of law at the time of the establishment of the link.
|
||||||
|
Illegal contents were not detected at the time of the linking. A permanent monitoring of the contents of linked
|
||||||
|
websites cannot be imposed without reasonable indications that there has been a violation of law. Illegal links
|
||||||
|
will be removed immediately at the time we get knowledge of them.</p>
|
||||||
|
<h2>Copyright</h2>
|
||||||
|
<p>Contents and compilations published on these websites by the providers are subject to German copyright laws.
|
||||||
|
Reproduction, editing, distribution as well as the use of any kind outside the scope of the copyright law require a
|
||||||
|
written permission of the author or originator. Downloads and copies of these websites are permitted for private use
|
||||||
|
only.<br /> The commercial use of our contents without permission of the originator is prohibited.</p>
|
||||||
|
<p>Copyright laws of third parties are respected as long as the contents on these websites do not originate from the
|
||||||
|
provider. Contributions of third parties on this site are indicated as such. However, if you notice any violations of
|
||||||
|
copyright law, please inform us. Such contents will be removed immediately.</p>
|
||||||
|
<p> </p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,88 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {% trans "Privacy Policy" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>FIXME</h1>
|
||||||
|
<h1>{% trans "Privacy Policy" %}</h1>
|
||||||
|
{% blocktrans %}
|
||||||
|
<h2>1. An overview of data protection</h2>
|
||||||
|
<h3>General</h3>
|
||||||
|
<p>The following gives a simple overview of what happens to your personal information when you visit our website.
|
||||||
|
Personal information is any data with which you could be personally identified. Detailed information on the subject
|
||||||
|
of data protection can be found in our privacy policy found below.</p>
|
||||||
|
<h3>Data collection on our website</h3>
|
||||||
|
<p><strong>Who is responsible for the data collection on this website?</strong></p>
|
||||||
|
<p>The data collected on this website are processed by the website operator. The operator's contact details can be found
|
||||||
|
in the website's required legal notice.</p>
|
||||||
|
<p><strong>How do we collect your data?</strong></p>
|
||||||
|
<p>Some data are collected when you provide it to us. This could, for example, be data you enter on a contact form.</p>
|
||||||
|
<p>Other data are collected automatically by our IT systems when you visit the website. These data are primarily technical
|
||||||
|
data such as the browser and operating system you are using or when you accessed the page. These data are collected
|
||||||
|
automatically as soon as you enter our website.</p>
|
||||||
|
<p><strong>What do we use your data for?</strong></p>
|
||||||
|
<p>Part of the data is collected to ensure the proper functioning of the website. Other data can be used to analyze how
|
||||||
|
visitors use the site.</p>
|
||||||
|
<p><strong>What rights do you have regarding your data?</strong></p>
|
||||||
|
<p>You always have the right to request information about your stored data, its origin, its recipients, and the purpose
|
||||||
|
of its collection at no charge. You also have the right to request that it be corrected, blocked, or deleted. You can
|
||||||
|
contact us at any time using the address given in the legal notice if you have further questions about the issue of
|
||||||
|
privacy and data protection. You may also, of course, file a complaint with the competent regulatory authorities.</p>
|
||||||
|
<h2>2. General information and mandatory information</h2>
|
||||||
|
<h3>Data protection</h3>
|
||||||
|
<p>The operators of this website take the protection of your personal data very seriously. We treat your personal data as
|
||||||
|
confidential and in accordance with the statutory data protection regulations and this privacy policy.</p>
|
||||||
|
<p>If you use this website, various pieces of personal data will be collected. Personal information is any data with which
|
||||||
|
you could be personally identified. This privacy policy explains what information we collect and what we use it for.
|
||||||
|
It also explains how and for what purpose this happens.</p>
|
||||||
|
<p>Please note that data transmitted via the internet (e.g. via email communication) may be subject to security breaches.
|
||||||
|
Complete protection of your data from third-party access is not possible.</p>
|
||||||
|
<h3>Notice concerning the party responsible for this website</h3>
|
||||||
|
<p>The party responsible for processing data on this website is:</p>
|
||||||
|
<p>Jim Martens<br />
|
||||||
|
Bindfeldweg 47d<br />
|
||||||
|
22459 Hamburg</p>
|
||||||
|
|
||||||
|
<p>Telephone: +49 40 55504288<br />
|
||||||
|
Email: admin@2martens.de</p>
|
||||||
|
<p>The responsible party is the natural or legal person who alone or jointly with others decides on the purposes and means
|
||||||
|
of processing personal data (names, email addresses, etc.).</p>
|
||||||
|
<h3>SSL or TLS encryption</h3> <p>This site uses SSL or TLS encryption for security reasons and for the protection of the
|
||||||
|
transmission of confidential content, such as the inquiries you send to us as the site operator. You can recognize an
|
||||||
|
encrypted connection in your browser's address line when it changes from "http://" to "https://" and the lock icon is
|
||||||
|
displayed in your browser's address bar.</p>
|
||||||
|
<p>If SSL or TLS encryption is activated, the data you transfer to us cannot be read by third parties.</p>
|
||||||
|
<h3>Opposition to promotional emails</h3> <p>We hereby expressly prohibit the use of contact data published in the context
|
||||||
|
of website legal notice requirements with regard to sending promotional and informational materials not expressly
|
||||||
|
requested. The website operator reserves the right to take specific legal action if unsolicited advertising material,
|
||||||
|
such as email spam, is received.</p>
|
||||||
|
<h2>3. Data collection on our website</h2>
|
||||||
|
<h3>Server log files</h3>
|
||||||
|
<p>The website provider automatically collects and stores information that your browser automatically transmits to us in
|
||||||
|
"server log files". These are:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Browser type and browser version</li>
|
||||||
|
<li>Operating system used</li>
|
||||||
|
<li>Referrer URL</li>
|
||||||
|
<li>Host name of the accessing computer</li>
|
||||||
|
<li>Time of the server request</li>
|
||||||
|
<li>IP address</li>
|
||||||
|
</ul>
|
||||||
|
<p>These data will not be combined with data from other sources.</p>
|
||||||
|
<p>The basis for data processing is Art. 6 (1) (b) GDPR, which allows the processing of data to fulfill a contract or
|
||||||
|
for measures preliminary to a contract.</p>
|
||||||
|
<h2>4. Plugins and tools</h2>
|
||||||
|
<h3>YouTube</h3>
|
||||||
|
<p>Our website uses plugins from YouTube, which is operated by Google. The operator of the pages is
|
||||||
|
YouTube LLC, 901 Cherry Ave., San Bruno, CA 94066, USA.</p>
|
||||||
|
<p>If you visit one of our pages featuring a YouTube plugin, a connection to the YouTube servers is established. Here
|
||||||
|
the YouTube server is informed about which of our pages you have visited.</p>
|
||||||
|
<p>If you're logged in to your YouTube account, YouTube allows you to associate your browsing behavior directly with your
|
||||||
|
personal profile. You can prevent this by logging out of your YouTube account.</p>
|
||||||
|
<p>YouTube is used to help make our website appealing. This constitutes a justified interest pursuant to
|
||||||
|
Art. 6 (1) (f) GDPR.</p>
|
||||||
|
<p>Further information about handling user data, can be found in the data protection declaration of YouTube under
|
||||||
|
<a href="https://www.google.de/intl/en/policies/privacy" target="_blank">https://www.google.de/intl/en/policies/privacy</a>.</p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<form method="post" action="{% url "edit_profile" %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ user_form|crispy }}
|
||||||
|
{{ profile_form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<form method="post" action="{% url "login" %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<input type="hidden" name="next" value="{{ next }}" />
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Login" %}</button>
|
||||||
|
<a href="{% url "password_reset" %}">{% trans "Forgot password?" %}</a>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site_name }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Change password" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
|
||||||
|
|
||||||
|
<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
{% if validlink %}
|
||||||
|
<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||||
|
<form method="post" action="{% url "password_reset" %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Change my password" %}</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<p>{% trans 'We’ve emailed you instructions for setting your password. If an account exists with the email you entered you should receive them shortly.' %}</p>
|
||||||
|
<p>{% trans 'If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.' %}</p>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {{ title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
<p>{% trans 'Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.' %}</p>
|
||||||
|
|
||||||
|
<form method="post" action="{% url "password_reset" %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Password reset" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{% extends "app/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block title %}{{ site.title }} - {% trans "Register" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans "Register a new user" %}</h1>
|
||||||
|
|
||||||
|
<form method="post" action="{% url "register" %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ user_form|crispy }}
|
||||||
|
{{ profile_form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Register" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2020 Jim Martens
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
from modeltranslation import translator
|
||||||
|
from modeltranslation.translator import TranslationOptions
|
||||||
|
|
||||||
|
|
||||||
|
# example for translation
|
||||||
|
# @translator.register(Gender)
|
||||||
|
# class GenderTranslationOptions(TranslationOptions):
|
||||||
|
# fields = ('name',)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
app_name = 'app'
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
path('legal-notice/', views.legal, name='legal'),
|
||||||
|
path('privacy/', views.privacy, name='privacy'),
|
||||||
|
]
|
|
@ -0,0 +1,122 @@
|
||||||
|
# coding=utf-8
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth import login
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
from django.contrib.auth.views import LoginView
|
||||||
|
from django.db import transaction
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from app.forms import ProfileForm
|
||||||
|
from app.forms import UserForm
|
||||||
|
|
||||||
|
|
||||||
|
def index(request) -> HttpResponse:
|
||||||
|
context = {
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
return render(request, template_name='app/home.html', context=context)
|
||||||
|
else:
|
||||||
|
return render(request, template_name='app/landing.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def register(request) -> HttpResponse:
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
return redirect('app:index')
|
||||||
|
|
||||||
|
user_form = UserCreationForm(data=request.POST or None)
|
||||||
|
profile_form = ProfileForm(data=request.POST or None, files=request.FILES or None)
|
||||||
|
context = {
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
},
|
||||||
|
'user_form': user_form,
|
||||||
|
'profile_form': profile_form
|
||||||
|
}
|
||||||
|
if request.method == "POST" and user_form.is_valid() and profile_form.is_valid():
|
||||||
|
user = user_form.save()
|
||||||
|
profile = profile_form.save(commit=False)
|
||||||
|
profile.user = user
|
||||||
|
if 'profile_pic' in request.FILES:
|
||||||
|
profile.profile_pic = request.FILES['profile_pic']
|
||||||
|
profile.save()
|
||||||
|
login(request, user=user)
|
||||||
|
messages.success(request, _('User was successfully registered'))
|
||||||
|
return redirect('edit_profile')
|
||||||
|
|
||||||
|
return render(request, template_name='registration/register.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
def user_login(request) -> HttpResponse:
|
||||||
|
login_view = LoginView()
|
||||||
|
login_view.setup(request)
|
||||||
|
login_view.redirect_authenticated_user = True
|
||||||
|
login_view.extra_context = {
|
||||||
|
'active': 'login',
|
||||||
|
'title': _('Login'),
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return login_view.dispatch(request)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
@transaction.atomic
|
||||||
|
def edit_profile(request) -> HttpResponse:
|
||||||
|
user_form = UserForm(data=request.POST or None, instance=request.user)
|
||||||
|
profile_form = ProfileForm(data=request.POST or None, files=request.FILES or None,
|
||||||
|
instance=request.user.profile)
|
||||||
|
user_form.fields['email'].help_text = _('The email address is required for password recovery.')
|
||||||
|
context = {
|
||||||
|
'active': 'edit_profile',
|
||||||
|
'title': _('Edit User Profile'),
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
},
|
||||||
|
'user_form': user_form,
|
||||||
|
'profile_form': profile_form
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.method == "POST" and user_form.is_valid() and profile_form.is_valid():
|
||||||
|
user_form.save()
|
||||||
|
profile = profile_form.save(commit=False)
|
||||||
|
if 'profile_pic' in request.FILES:
|
||||||
|
profile.profile_pic = request.FILES['profile_pic']
|
||||||
|
profile.save()
|
||||||
|
messages.success(request, _('Profile was successfully updated'))
|
||||||
|
|
||||||
|
return render(request, template_name='registration/edit_profile.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def password_change_done(request) -> HttpResponse:
|
||||||
|
messages.success(request, _('Your password was successfully changed.'))
|
||||||
|
return redirect(reverse('edit_profile'))
|
||||||
|
|
||||||
|
|
||||||
|
def legal(request) -> HttpResponse:
|
||||||
|
context = {
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return render(request, template_name='app/legal.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
def privacy(request) -> HttpResponse:
|
||||||
|
context = {
|
||||||
|
'site': {
|
||||||
|
'title': 'Django template'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return render(request, template_name='app/privacy.html', context=context)
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding=utf-8
|
||||||
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chaos_dating_project.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,30 @@
|
||||||
|
{
|
||||||
|
"name": "django-template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Django template",
|
||||||
|
"main": "index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "^4.4.1",
|
||||||
|
"jquery": "^3.4.1",
|
||||||
|
"js-yaml": "3.13.1",
|
||||||
|
"popper.js": "^1.16.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^9.7.3",
|
||||||
|
"node-sass": "^4.12.0",
|
||||||
|
"sass-lint": "^1.13.1",
|
||||||
|
"eslint": "^4.18.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"compile:css": "node-sass -o static/css static/sass",
|
||||||
|
"compile:css:watch": "node-sass -o static/css static/sass --watch",
|
||||||
|
"lint:css": "sass-lint static/sass/** -v -q"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.2martens.de/2martens/django-template.git"
|
||||||
|
},
|
||||||
|
"author": "Jim Martens",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
# coding=utf-8
|
|
@ -0,0 +1,17 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""
|
||||||
|
ASGI config for 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.0/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
|
@ -0,0 +1,150 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""
|
||||||
|
Django settings for project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 3.0.1.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'w$#!92p2fg8lykxr*aqi-&0llq81xq+7pe^733p(qt*n!0g_ci')
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = os.environ.get('DJANGO_DEBUG', 'True') != 'False'
|
||||||
|
|
||||||
|
# extend with allowed production hosts
|
||||||
|
ALLOWED_HOSTS = ['localhost', '127.0.0.1', '[::1]']
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'app.apps.DjangoTemplateConfig', # TODO: change to your app config class
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'crispy_forms',
|
||||||
|
'modeltranslation',
|
||||||
|
]
|
||||||
|
|
||||||
|
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 = 'project.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',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'project.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/3.0/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/3.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
AUTH_PROFILE_MODULE = 'app.Profile'
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = 'app:index'
|
||||||
|
LOGOUT_REDIRECT_URL = 'app:index'
|
||||||
|
LOGIN_URL = 'login'
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'Europe/Berlin'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
LANGUAGES = [
|
||||||
|
('en-us', _('English')),
|
||||||
|
('de-de', _('German')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = '/static/'
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
os.path.join(BASE_DIR, "static"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
SECURE_SSL_REDIRECT = not DEBUG
|
||||||
|
SESSION_COOKIE_SECURE = not DEBUG
|
||||||
|
CSRF_COOKIE_SECURE = not DEBUG
|
||||||
|
SECURE_REFERRER_POLICY = 'same-origin'
|
|
@ -0,0 +1,27 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""project URL Configuration
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/3.0/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 include
|
||||||
|
from django.urls import path
|
||||||
|
from app import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('app/', include('app.urls')),
|
||||||
|
path('accounts/', include('app.account_urls')),
|
||||||
|
path('', views.index)
|
||||||
|
]
|
|
@ -0,0 +1,17 @@
|
||||||
|
# coding=utf-8
|
||||||
|
"""
|
||||||
|
WSGI config for 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.0/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
|
@ -0,0 +1,3 @@
|
||||||
|
django==3.0.3
|
||||||
|
django-crispy-forms==1.8.1
|
||||||
|
django-modeltranslation==0.14.2
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,11 @@
|
||||||
|
/*!
|
||||||
|
* Bootstrap v4.3.1 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2019 The Bootstrap Authors
|
||||||
|
* Copyright 2011-2019 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// overwrite variables
|
||||||
|
$body-bg: #fdfdfd;
|
||||||
|
$enable-responsive-font-sizes: true;
|
||||||
|
@import "../../node_modules/bootstrap/scss/bootstrap";
|
|
@ -0,0 +1,342 @@
|
||||||
|
svg:not(:root).svg-inline--fa {
|
||||||
|
overflow: visible; }
|
||||||
|
|
||||||
|
.svg-inline--fa {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: inherit;
|
||||||
|
height: 1em;
|
||||||
|
overflow: visible;
|
||||||
|
vertical-align: -.125em; }
|
||||||
|
.svg-inline--fa.fa-lg {
|
||||||
|
vertical-align: -.225em; }
|
||||||
|
.svg-inline--fa.fa-w-1 {
|
||||||
|
width: 0.0625em; }
|
||||||
|
.svg-inline--fa.fa-w-2 {
|
||||||
|
width: 0.125em; }
|
||||||
|
.svg-inline--fa.fa-w-3 {
|
||||||
|
width: 0.1875em; }
|
||||||
|
.svg-inline--fa.fa-w-4 {
|
||||||
|
width: 0.25em; }
|
||||||
|
.svg-inline--fa.fa-w-5 {
|
||||||
|
width: 0.3125em; }
|
||||||
|
.svg-inline--fa.fa-w-6 {
|
||||||
|
width: 0.375em; }
|
||||||
|
.svg-inline--fa.fa-w-7 {
|
||||||
|
width: 0.4375em; }
|
||||||
|
.svg-inline--fa.fa-w-8 {
|
||||||
|
width: 0.5em; }
|
||||||
|
.svg-inline--fa.fa-w-9 {
|
||||||
|
width: 0.5625em; }
|
||||||
|
.svg-inline--fa.fa-w-10 {
|
||||||
|
width: 0.625em; }
|
||||||
|
.svg-inline--fa.fa-w-11 {
|
||||||
|
width: 0.6875em; }
|
||||||
|
.svg-inline--fa.fa-w-12 {
|
||||||
|
width: 0.75em; }
|
||||||
|
.svg-inline--fa.fa-w-13 {
|
||||||
|
width: 0.8125em; }
|
||||||
|
.svg-inline--fa.fa-w-14 {
|
||||||
|
width: 0.875em; }
|
||||||
|
.svg-inline--fa.fa-w-15 {
|
||||||
|
width: 0.9375em; }
|
||||||
|
.svg-inline--fa.fa-w-16 {
|
||||||
|
width: 1em; }
|
||||||
|
.svg-inline--fa.fa-w-17 {
|
||||||
|
width: 1.0625em; }
|
||||||
|
.svg-inline--fa.fa-w-18 {
|
||||||
|
width: 1.125em; }
|
||||||
|
.svg-inline--fa.fa-w-19 {
|
||||||
|
width: 1.1875em; }
|
||||||
|
.svg-inline--fa.fa-w-20 {
|
||||||
|
width: 1.25em; }
|
||||||
|
.svg-inline--fa.fa-pull-left {
|
||||||
|
margin-right: .3em;
|
||||||
|
width: auto; }
|
||||||
|
.svg-inline--fa.fa-pull-right {
|
||||||
|
margin-left: .3em;
|
||||||
|
width: auto; }
|
||||||
|
.svg-inline--fa.fa-border {
|
||||||
|
height: 1.5em; }
|
||||||
|
.svg-inline--fa.fa-li {
|
||||||
|
width: 2em; }
|
||||||
|
.svg-inline--fa.fa-fw {
|
||||||
|
width: 1.25em; }
|
||||||
|
|
||||||
|
.fa-layers svg.svg-inline--fa {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0; }
|
||||||
|
|
||||||
|
.fa-layers {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: -.125em;
|
||||||
|
width: 1em; }
|
||||||
|
.fa-layers svg.svg-inline--fa {
|
||||||
|
-webkit-transform-origin: center center;
|
||||||
|
transform-origin: center center; }
|
||||||
|
|
||||||
|
.fa-layers-text, .fa-layers-counter {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center; }
|
||||||
|
|
||||||
|
.fa-layers-text {
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
-webkit-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
-webkit-transform-origin: center center;
|
||||||
|
transform-origin: center center; }
|
||||||
|
|
||||||
|
.fa-layers-counter {
|
||||||
|
background-color: #ff253a;
|
||||||
|
border-radius: 1em;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #fff;
|
||||||
|
height: 1.5em;
|
||||||
|
line-height: 1;
|
||||||
|
max-width: 5em;
|
||||||
|
min-width: 1.5em;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: .25em;
|
||||||
|
right: 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform: scale(0.25);
|
||||||
|
transform: scale(0.25);
|
||||||
|
-webkit-transform-origin: top right;
|
||||||
|
transform-origin: top right; }
|
||||||
|
|
||||||
|
.fa-layers-bottom-right {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
top: auto;
|
||||||
|
-webkit-transform: scale(0.25);
|
||||||
|
transform: scale(0.25);
|
||||||
|
-webkit-transform-origin: bottom right;
|
||||||
|
transform-origin: bottom right; }
|
||||||
|
|
||||||
|
.fa-layers-bottom-left {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
-webkit-transform: scale(0.25);
|
||||||
|
transform: scale(0.25);
|
||||||
|
-webkit-transform-origin: bottom left;
|
||||||
|
transform-origin: bottom left; }
|
||||||
|
|
||||||
|
.fa-layers-top-right {
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform: scale(0.25);
|
||||||
|
transform: scale(0.25);
|
||||||
|
-webkit-transform-origin: top right;
|
||||||
|
transform-origin: top right; }
|
||||||
|
|
||||||
|
.fa-layers-top-left {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform: scale(0.25);
|
||||||
|
transform: scale(0.25);
|
||||||
|
-webkit-transform-origin: top left;
|
||||||
|
transform-origin: top left; }
|
||||||
|
|
||||||
|
.fa-lg {
|
||||||
|
font-size: 1.33333em;
|
||||||
|
line-height: 0.75em;
|
||||||
|
vertical-align: -.0667em; }
|
||||||
|
|
||||||
|
.fa-xs {
|
||||||
|
font-size: .75em; }
|
||||||
|
|
||||||
|
.fa-sm {
|
||||||
|
font-size: .875em; }
|
||||||
|
|
||||||
|
.fa-1x {
|
||||||
|
font-size: 1em; }
|
||||||
|
|
||||||
|
.fa-2x {
|
||||||
|
font-size: 2em; }
|
||||||
|
|
||||||
|
.fa-3x {
|
||||||
|
font-size: 3em; }
|
||||||
|
|
||||||
|
.fa-4x {
|
||||||
|
font-size: 4em; }
|
||||||
|
|
||||||
|
.fa-5x {
|
||||||
|
font-size: 5em; }
|
||||||
|
|
||||||
|
.fa-6x {
|
||||||
|
font-size: 6em; }
|
||||||
|
|
||||||
|
.fa-7x {
|
||||||
|
font-size: 7em; }
|
||||||
|
|
||||||
|
.fa-8x {
|
||||||
|
font-size: 8em; }
|
||||||
|
|
||||||
|
.fa-9x {
|
||||||
|
font-size: 9em; }
|
||||||
|
|
||||||
|
.fa-10x {
|
||||||
|
font-size: 10em; }
|
||||||
|
|
||||||
|
.fa-fw {
|
||||||
|
text-align: center;
|
||||||
|
width: 1.25em; }
|
||||||
|
|
||||||
|
.fa-ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-left: 2.5em;
|
||||||
|
padding-left: 0; }
|
||||||
|
.fa-ul > li {
|
||||||
|
position: relative; }
|
||||||
|
|
||||||
|
.fa-li {
|
||||||
|
left: -2em;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
width: 2em;
|
||||||
|
line-height: inherit; }
|
||||||
|
|
||||||
|
.fa-border {
|
||||||
|
border: solid 0.08em #eee;
|
||||||
|
border-radius: .1em;
|
||||||
|
padding: .2em .25em .15em; }
|
||||||
|
|
||||||
|
.fa-pull-left {
|
||||||
|
float: left; }
|
||||||
|
|
||||||
|
.fa-pull-right {
|
||||||
|
float: right; }
|
||||||
|
|
||||||
|
.fa.fa-pull-left,
|
||||||
|
.fas.fa-pull-left,
|
||||||
|
.far.fa-pull-left,
|
||||||
|
.fal.fa-pull-left,
|
||||||
|
.fab.fa-pull-left {
|
||||||
|
margin-right: .3em; }
|
||||||
|
|
||||||
|
.fa.fa-pull-right,
|
||||||
|
.fas.fa-pull-right,
|
||||||
|
.far.fa-pull-right,
|
||||||
|
.fal.fa-pull-right,
|
||||||
|
.fab.fa-pull-right {
|
||||||
|
margin-left: .3em; }
|
||||||
|
|
||||||
|
.fa-spin {
|
||||||
|
-webkit-animation: fa-spin 2s infinite linear;
|
||||||
|
animation: fa-spin 2s infinite linear; }
|
||||||
|
|
||||||
|
.fa-pulse {
|
||||||
|
-webkit-animation: fa-spin 1s infinite steps(8);
|
||||||
|
animation: fa-spin 1s infinite steps(8); }
|
||||||
|
|
||||||
|
@-webkit-keyframes fa-spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg); }
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg); } }
|
||||||
|
|
||||||
|
@keyframes fa-spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg); }
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg); } }
|
||||||
|
|
||||||
|
.fa-rotate-90 {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg); }
|
||||||
|
|
||||||
|
.fa-rotate-180 {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
transform: rotate(180deg); }
|
||||||
|
|
||||||
|
.fa-rotate-270 {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
|
||||||
|
-webkit-transform: rotate(270deg);
|
||||||
|
transform: rotate(270deg); }
|
||||||
|
|
||||||
|
.fa-flip-horizontal {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
|
||||||
|
-webkit-transform: scale(-1, 1);
|
||||||
|
transform: scale(-1, 1); }
|
||||||
|
|
||||||
|
.fa-flip-vertical {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
|
||||||
|
-webkit-transform: scale(1, -1);
|
||||||
|
transform: scale(1, -1); }
|
||||||
|
|
||||||
|
.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
|
||||||
|
-webkit-transform: scale(-1, -1);
|
||||||
|
transform: scale(-1, -1); }
|
||||||
|
|
||||||
|
:root .fa-rotate-90,
|
||||||
|
:root .fa-rotate-180,
|
||||||
|
:root .fa-rotate-270,
|
||||||
|
:root .fa-flip-horizontal,
|
||||||
|
:root .fa-flip-vertical,
|
||||||
|
:root .fa-flip-both {
|
||||||
|
-webkit-filter: none;
|
||||||
|
filter: none; }
|
||||||
|
|
||||||
|
.fa-stack {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2em;
|
||||||
|
position: relative;
|
||||||
|
width: 2.5em; }
|
||||||
|
|
||||||
|
.fa-stack-1x,
|
||||||
|
.fa-stack-2x {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0; }
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-stack-1x {
|
||||||
|
height: 1em;
|
||||||
|
width: 1.25em; }
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-stack-2x {
|
||||||
|
height: 2em;
|
||||||
|
width: 2.5em; }
|
||||||
|
|
||||||
|
.fa-inverse {
|
||||||
|
color: #fff; }
|
||||||
|
|
||||||
|
.sr-only {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px; }
|
||||||
|
|
||||||
|
.sr-only-focusable:active, .sr-only-focusable:focus {
|
||||||
|
clip: auto;
|
||||||
|
height: auto;
|
||||||
|
margin: 0;
|
||||||
|
overflow: visible;
|
||||||
|
position: static;
|
||||||
|
width: auto; }
|
|
@ -0,0 +1,59 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
@import "bootstrap-custom";
|
||||||
|
@import "fa-svg-with-js";
|
||||||
|
|
||||||
|
.site-header > .navbar {
|
||||||
|
//border-top: 5px solid $dark;
|
||||||
|
border-bottom: 2px solid $light;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nav tabs
|
||||||
|
.nav-tabs {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.euro {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// back-to-top button
|
||||||
|
#back-to-top {
|
||||||
|
cursor: pointer;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
bottom: 40px;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$navbarHeight: 58px;
|
||||||
|
|
||||||
|
#main {
|
||||||
|
margin-top: $navbarHeight + 15px;
|
||||||
|
margin-bottom: $navbarHeight + 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main.submenu {
|
||||||
|
margin-top: 2*$navbarHeight + 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#countdown:before {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header > .navbar {
|
||||||
|
background-color: $body-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer {
|
||||||
|
border-top: 2px solid $light;
|
||||||
|
background-color: $body-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anchor {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
top: -$navbarHeight;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Required meta tags -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
{% block meta %}{% endblock %}
|
||||||
|
|
||||||
|
<!-- FontAwesome -->
|
||||||
|
<script defer src="{% static "js/all.js" %}"></script>
|
||||||
|
<link type="text/css" href="{% static 'css/main.css' %}" rel="stylesheet" media="screen">
|
||||||
|
|
||||||
|
<title>{% block title %}{% endblock %}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header class="site-header">
|
||||||
|
{% block header %}{% endblock %}
|
||||||
|
</header>
|
||||||
|
<div id="main">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
{% if messages %}
|
||||||
|
{% for message in messages %}
|
||||||
|
<div class="alert alert-{{ message.tags }}">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<main class="col">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<button id="back-to-top"
|
||||||
|
class="btn btn-primary btn-lg"
|
||||||
|
title="Click to return to the start of the page" data-toggle="tooltip" data-placement="left">
|
||||||
|
<span class="fas fa-chevron-up"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="site-footer small text-muted py-3">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
{% block footer %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- Optional JavaScript -->
|
||||||
|
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
|
||||||
|
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
|
||||||
|
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
{% block javascripts %}{% endblock %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue