Basic infrastructure work

This commit is contained in:
Phillip Stephens
2019-07-07 06:16:07 -07:00
commit cb8668bbcc
72 changed files with 2402 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
*.pyc
*~
__pycache__
*venv*
db.sqlite3
/static
/media
/martor
.DS_Store
View File
+31
View File
@@ -0,0 +1,31 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import Profile
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
verbose_name_plural = 'Profile'
fk_name = 'user'
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline, )
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'get_location')
list_select_related = ('profile', )
def get_location(self, instance):
return instance.profile.location
get_location.short_description = 'Location'
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
+5
View File
@@ -0,0 +1,5 @@
from django.apps import AppConfig
class AccountsConfig(AppConfig):
name = 'accounts'
+50
View File
@@ -0,0 +1,50 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Profile
class SignUpForm(UserCreationForm):
email = forms.CharField(max_length=254, required=True, widget=forms.EmailInput())
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
class ProfileForm(forms.ModelForm):
first_name = forms.CharField(max_length=256)
last_name = forms.CharField(max_length=256)
email = forms.EmailField(max_length=254, required=True, widget=forms.EmailInput())
use_gravatar = forms.BooleanField(label='Use avatars from Gravatar?', required=False)
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
try:
self.fields['use_gravatar'].initial = self.instance.profile.use_gravatar
self.fields['avatar'].initial = self.instance.profile.avatar
self.fields['first_name'].initial = self.instance.first_name
self.fields['last_name'].initial = self.instance.last_name
self.fields['email'].initial = self.instance.email
self.fields['location'].initial = self.instance.profile.location
except User.DoesNotExist:
pass
class Meta:
model = Profile
fields = ['avatar', 'first_name', 'last_name', 'email', 'use_gravatar', 'location', ]
exclude = ['user']
def save(self, commit=True):
super(ProfileForm, self).save(commit)
self.instance.profile.use_gravatar = self.cleaned_data['use_gravatar']
if self.cleaned_data['avatar'] is not False:
self.instance.profile.avatar = self.cleaned_data['avatar']
else:
self.instance.profile.avatar = None
self.instance.profile.location = self.cleaned_data['location']
self.instance.profile.save()
self.instance.save()
return self.instance
+29
View File
@@ -0,0 +1,29 @@
# Generated by Django 2.2.3 on 2019-07-07 12:44
import accounts.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('avatar', models.ImageField(blank=True, null=True, upload_to=accounts.models.path_and_rename)),
('birthdate', models.DateTimeField(blank=True, null=True)),
('use_gravatar', models.BooleanField(blank=True, default=False)),
('location', models.CharField(blank=True, max_length=100, null=True)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
View File
+38
View File
@@ -0,0 +1,38 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
import os
from uuid import uuid4
def path_and_rename(instance, filename):
upload_to = 'avatars/'
ext = filename.split('.')[-1]
# get filename
if instance.pk:
filename = '{}.{}'.format(instance.pk, ext)
else:
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(upload_to, filename)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to=path_and_rename, null=True, blank=True)
birthdate = models.DateTimeField(null=True, blank=True)
use_gravatar = models.BooleanField(blank=True, default=False)
location = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

+11
View File
@@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block body %}
<div class="container">
<h1 class="text-center logo my-4">
<a href="{% url 'home' %}" class="text-light">AxioDL</a>
</h1>
{% block content %}
{% endblock %}
</div>
{% endblock %}
+31
View File
@@ -0,0 +1,31 @@
{% extends 'base_accounts.html' %}
{% block title %}Log in to AxioDL{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-4 col-md-6 col-sm-8">
<div class="card border-dark">
<div class="card-header bg-dark text-light">
<div class="card-title"><h2 class="card-title">Log in</h2></div>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-primary btn-block">Log in</button>
</form>
</div>
<div class="card-footer text-muted text-center">
New to AxioDL? <a href="{% url 'signup' %}">Sign up</a>
</div>
</div>
<div class="text-center py-2">
<small>
<a href="{% url 'password_reset' %}" class="text-muted">Forgot your password?</a>
</small>
</div>
</div>
</div>
{% endblock %}
+26
View File
@@ -0,0 +1,26 @@
{% extends 'base.html' %}
{% block title %}Change password{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item active">Change password</li>
{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-6 col-md-8 col-sm-10">
<div class="card border-dark">
<div class="card-header bg-dark text-light">
<div class="card-title"><h2 class="card-title">Change your password</h2></div>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-success btn-block">Change password</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% block title %}Change password successful{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item"><a href="{% url 'password_change' %}">Change password</a></li>
<li class="breadcrumb-item active">Success</li>
{% endblock %}
{% block content %}
<div class="alert alert-success" role="alert">
<strong>Success!</strong> Your password has been changed!
</div>
<a href="{% url 'home' %}" class="btn btn-secondary">Return to home page</a>
{% endblock %}
+23
View File
@@ -0,0 +1,23 @@
{% extends 'base_accounts.html' %}
{% block title %}Reset your password{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-4 col-md-6 col-sm-8">
<div class="card border-dark">
<div class="card-header bg-dark text-light">
<div class="card-title"><h2 class="card-title">Reset your password</h2></div>
</div>
<div class="card-body">
<p>Enter your email address and we will send you a link to reset your password.</p>
<form method="post" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-primary btn-block">Send password reset email</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,20 @@
{% extends 'base_accounts.html' %}
{% block title %}Password changed!{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-6 col-md-8 col-sm-10">
<div class="card border-dark">
<div class="card-header bg-dark text-light">
<div class="card-title"><h2 class="card-title">Password changed!</h2></div>
<div class="card-body">
<div class="alert alert-success" role="alert">
You have successfully changed your password! You may now proceed to log in.
</div>
<a href="{% url 'login' %}" class="btn btn-secondary btn-block">Return to log in</a>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,34 @@
{% extends 'base_accounts.html' %}
{% block title %}
{% if validlink %}
Change password for {{ form.user.username }}
{% else %}
Reset your password
{% endif %}
{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-6 col-md-8 col-sm-10">
<div class="card">
<div class="card-body">
{% if validlink %}
<h3 class="card-title">Change password for {{ form.user.username }}</h3>
<form method="post" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-success btn-block">Change password</button>
</form>
{% else %}
<h3 class="card-title">Reset your password</h3>
<div class="alert alert-danger" role="alert">
It looks like you clicked on an invalid password reset link. Please try again.
</div>
<a href="{% url 'password_reset' %}" class="btn btn-secondary btn-block">Request a new password reset link</a>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,17 @@
{% extends 'base_accounts.html' %}
{% block title %}Reset your password{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-5 col-md-6 col-sm-8">
<div class="card">
<div class="card-body">
<h3 class="card-title">Reset your password</h3>
<p>Check your email for a link to reset your password.<br />If it doesn't appear within a few minutes, check your spam folder.</p>
<a href="{% url 'login' %}" class="btn btn-secondary btn-block">Return to log in</a>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,19 @@
Hi there,
Someone asked for a password reset for the email address {{ email }}.
Follow the link below:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
In case you forgot your AxioDL username: {{ user.username }}
If clicking the link above doesn't work, please copy and paste the URL
in a new browser window instead.
If you've received this mail in error, it's likely that another user entered
your email address by mistake while trying to reset a password. If you didn't
initiate the request, you don't need to take any further action and can safely
disregard this email.
Thanks,
The AxioDL Team
@@ -0,0 +1 @@
[AxioDL] Please reset your password
+25
View File
@@ -0,0 +1,25 @@
{% extends 'base_accounts.html' %}
{% block title %}Sign up to Django Boards{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8 col-md-10 col-sm-12">
<div class="card border-dark">
<div class="card-header bg-dark text-light">
<div class="card-title"><h2 class="card-title">Sign up</h2></div>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
{% include 'includes/form.html' %}
<button type="submit" class="btn btn-primary btn-block">Create an account</button>
</form>
</div>
<div class="card-footer text-muted text-center">
Already have an account? <a href="{% url 'login' %}">Log in</a>
</div>
</div>
</div>
</div>
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More