generated from 2martens/django-template
Initial commit
This commit is contained in:
2
app/__init__.py
Normal file
2
app/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
# coding=utf-8
|
||||
default_app_config = 'chaos_dating.apps.ChaosDatingConfig'
|
||||
39
app/account_urls.py
Normal file
39
app/account_urls.py
Normal file
@ -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'),
|
||||
]
|
||||
20
app/admin.py
Normal file
20
app/admin.py
Normal file
@ -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)
|
||||
|
||||
7
app/apps.py
Normal file
7
app/apps.py
Normal file
@ -0,0 +1,7 @@
|
||||
# coding=utf-8
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class DjangoTemplateConfig(AppConfig):
|
||||
name = 'app'
|
||||
verbose_name = 'Django template app'
|
||||
44
app/forms.py
Normal file
44
app/forms.py
Normal file
@ -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
|
||||
|
||||
1
app/migrations/__init__.py
Normal file
1
app/migrations/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# coding=utf-8
|
||||
11
app/models.py
Normal file
11
app/models.py
Normal file
@ -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
app/templates/app/.gitkeep
Normal file
0
app/templates/app/.gitkeep
Normal file
60
app/templates/app/base.html
Normal file
60
app/templates/app/base.html
Normal file
@ -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 %}
|
||||
9
app/templates/app/home.html
Normal file
9
app/templates/app/home.html
Normal file
@ -0,0 +1,9 @@
|
||||
{% extends "app/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ site.title }} - {% trans "Home" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans "Home" %}</h1>
|
||||
|
||||
{% endblock %}
|
||||
38
app/templates/app/landing.html
Normal file
38
app/templates/app/landing.html
Normal file
@ -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 %}
|
||||
48
app/templates/app/legal.html
Normal file
48
app/templates/app/legal.html
Normal file
@ -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 %}
|
||||
88
app/templates/app/privacy.html
Normal file
88
app/templates/app/privacy.html
Normal file
@ -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 %}
|
||||
17
app/templates/registration/edit_profile.html
Normal file
17
app/templates/registration/edit_profile.html
Normal file
@ -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 %}
|
||||
|
||||
17
app/templates/registration/login.html
Normal file
17
app/templates/registration/login.html
Normal file
@ -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 %}
|
||||
15
app/templates/registration/password_change_form.html
Normal file
15
app/templates/registration/password_change_form.html
Normal file
@ -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 %}
|
||||
13
app/templates/registration/password_reset_complete.html
Normal file
13
app/templates/registration/password_reset_complete.html
Normal file
@ -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 %}
|
||||
19
app/templates/registration/password_reset_confirm.html
Normal file
19
app/templates/registration/password_reset_confirm.html
Normal file
@ -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 %}
|
||||
13
app/templates/registration/password_reset_done.html
Normal file
13
app/templates/registration/password_reset_done.html
Normal file
@ -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 %}
|
||||
17
app/templates/registration/password_reset_form.html
Normal file
17
app/templates/registration/password_reset_form.html
Normal file
@ -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 %}
|
||||
16
app/templates/registration/register.html
Normal file
16
app/templates/registration/register.html
Normal file
@ -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 %}
|
||||
5
app/tests.py
Normal file
5
app/tests.py
Normal file
@ -0,0 +1,5 @@
|
||||
# coding=utf-8
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
# Create your tests here.
|
||||
24
app/translation.py
Normal file
24
app/translation.py
Normal file
@ -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',)
|
||||
|
||||
11
app/urls.py
Normal file
11
app/urls.py
Normal file
@ -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'),
|
||||
]
|
||||
122
app/views.py
Normal file
122
app/views.py
Normal file
@ -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)
|
||||
Reference in New Issue
Block a user