port to new django, AI automated

This commit is contained in:
2026-03-30 22:35:36 +02:00
parent e2d166e437
commit 372da3caa9
215 changed files with 9283 additions and 2981 deletions

View File

@@ -1,32 +1,128 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from musicians.models import Musician
# from eventplanner.admin import EventParticipationInline
from django.utils.translation import gettext_lazy as _
from .models import Musician
# Define an inline admin descriptor for Musician model
# which acts a bit like a singleton
class MusicianInline(admin.StackedInline):
"""Inline admin for Musician model attached to User."""
model = Musician
can_delete = False
verbose_name_plural = _('musicians')
verbose_name = _('musician')
verbose_name_plural = _("musician profile")
verbose_name = _("musician profile")
fieldsets = (
(
_("Images"),
{
"fields": ("image", "small_image"),
"classes": ("collapse",),
},
),
(
_("Contact"),
{
"fields": ("phone_home", "phone_mobile", "phone_work"),
},
),
(
_("Address"),
{
"fields": ("street", "city", "zip_code"),
},
),
(
_("Details"),
{
"fields": ("instrument", "birthday", "position", "public_description"),
},
),
)
# Define a new User admin
class UserAdmin(UserAdmin):
class CustomUserAdmin(BaseUserAdmin):
"""Extended User admin with Musician inline."""
inlines = (MusicianInline,)
list_display = (
"username",
"email",
"first_name",
"last_name",
"is_staff",
"get_instrument",
)
list_select_related = ("musician",)
@admin.display(description=_("Instrument"))
def get_instrument(self, obj):
try:
return obj.musician.get_instrument_display()
except Musician.DoesNotExist:
return "-"
@admin.register(Musician)
class MusicianAdmin(admin.ModelAdmin):
readonly_fields = ('user',)
# inlines = ( EventParticipationInline, )
model = Musician
"""Admin configuration for Musician model."""
list_display = (
"user",
"instrument",
"phone_mobile",
"city",
"position",
)
list_filter = ("instrument",)
search_fields = (
"user__username",
"user__first_name",
"user__last_name",
"city",
"phone_mobile",
)
readonly_fields = ("user",)
ordering = ("position", "user__username")
fieldsets = (
(
None,
{
"fields": ("user", "instrument", "position"),
},
),
(
_("Images"),
{
"fields": ("image", "small_image"),
"classes": ("collapse",),
},
),
(
_("Contact Information"),
{
"fields": ("phone_home", "phone_mobile", "phone_work"),
},
),
(
_("Address"),
{
"fields": ("street", "city", "zip_code"),
},
),
(
_("Personal"),
{
"fields": ("birthday", "public_description"),
"classes": ("collapse",),
},
),
)
# Re-register UserAdmin
# Re-register UserAdmin with Musician inline
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
admin.site.register(Musician, MusicianAdmin)
admin.site.register(User, CustomUserAdmin)

View File

@@ -0,0 +1,40 @@
# Generated by Django 5.1.15 on 2026-03-30 19:15
import django.db.models.deletion
import musicians.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Musician',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.ImageField(blank=True, null=True, upload_to=musicians.models.musicianPictureName, verbose_name='image')),
('small_image', models.ImageField(blank=True, null=True, upload_to=musicians.models.musicianSmallPictureName, verbose_name='circular thumbnail')),
('instrument', models.CharField(blank=True, choices=[('TR', 'Trumpet'), ('TRB', 'Trombone'), ('HRN', 'Horn'), ('TUBA', 'Tuba')], max_length=4, verbose_name='instrument')),
('birthday', models.DateField(blank=True, null=True, verbose_name='birthday')),
('street', models.CharField(blank=True, max_length=80, verbose_name='street')),
('city', models.CharField(blank=True, max_length=40, verbose_name='city')),
('zip_code', models.IntegerField(blank=True, null=True, verbose_name='zip_code')),
('phone_home', models.CharField(blank=True, max_length=18, verbose_name='phone_home')),
('phone_mobile', models.CharField(blank=True, max_length=18, verbose_name='phone_mobile')),
('phone_work', models.CharField(blank=True, max_length=18, verbose_name='phone_work')),
('position', models.IntegerField(blank=True, null=True, verbose_name='Position')),
('public_description', models.TextField(blank=True, verbose_name='public_description')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'ordering': ['position', 'user__username'],
},
),
]

View File

View File

@@ -1,14 +1,14 @@
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
import os
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _
INSTRUMENTS = (
('TR', _('Trumpet')),
('TRB', _('Trombone')),
('HRN', _('Horn')),
('TUBA', _('Tuba'))
("TR", _("Trumpet")),
("TRB", _("Trombone")),
("HRN", _("Horn")),
("TUBA", _("Tuba")),
)
@@ -24,35 +24,58 @@ def musicianSmallPictureName(musician, originalName):
class Musician(models.Model):
# Link to user object, contains first name and last name
user = models.OneToOneField(User, verbose_name=_("user"), on_delete=models.CASCADE)
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name=_("user"))
image = models.ImageField(upload_to=musicianPictureName, verbose_name=_("image"))
small_image = models.ImageField(upload_to=musicianSmallPictureName, verbose_name=_("circular thumbnail"))
image = models.ImageField(
upload_to=musicianPictureName,
verbose_name=_("image"),
blank=True,
null=True,
)
small_image = models.ImageField(
upload_to=musicianSmallPictureName,
verbose_name=_("circular thumbnail"),
blank=True,
null=True,
)
# Properties
instrument = models.CharField(max_length=4, choices=INSTRUMENTS, blank=True, verbose_name=_("instrument"))
instrument = models.CharField(
max_length=4, choices=INSTRUMENTS, blank=True, verbose_name=_("instrument")
)
birthday = models.DateField(null=True, verbose_name=_("birthday"))
birthday = models.DateField(null=True, blank=True, verbose_name=_("birthday"))
street = models.CharField(max_length=80, blank=True, verbose_name=_("street"))
city = models.CharField(max_length=40, blank=True, verbose_name=_("city"))
zip_code = models.IntegerField(null=True, verbose_name=_("zip_code"))
zip_code = models.IntegerField(null=True, blank=True, verbose_name=_("zip_code"))
phone_home = models.CharField(max_length=18, blank=True, verbose_name=_("phone_home"))
phone_mobile = models.CharField(max_length=18, blank=True, verbose_name=_("phone_mobile"))
phone_work = models.CharField(max_length=18, blank=True, verbose_name=_("phone_work"))
phone_home = models.CharField(
max_length=18, blank=True, verbose_name=_("phone_home")
)
phone_mobile = models.CharField(
max_length=18, blank=True, verbose_name=_("phone_mobile")
)
phone_work = models.CharField(
max_length=18, blank=True, verbose_name=_("phone_work")
)
position = models.IntegerField(null=True, verbose_name=_("Position"))
position = models.IntegerField(null=True, blank=True, verbose_name=_("Position"))
public_description = models.TextField(blank=True, verbose_name=_("public_description"))
public_description = models.TextField(
blank=True, verbose_name=_("public_description")
)
class Meta:
ordering = ["position", "user__username"]
@property
def isDeepBrass(self):
return self.instrument == 'TRB' or self.instrument == "EUPH" or self.instrument == "TUBA" or self.instrument == "HRN"
return self.instrument in ("TRB", "EUPH", "TUBA", "HRN")
@property
def isHighBrass(self):
return self.instrument == 'TR'
return self.instrument == "TR"
def __unicode__(self):
def __str__(self):
return self.user.username

View File

@@ -1,178 +1,236 @@
{% extends "website/base.html" %}
{% load sekizai_tags staticfiles %}
{% block content %}
{% addtoblock "css" strip %}<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/portfolio.css" media="screen, projection">{% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/lib/isotope.css">{% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}css/lib/animate.css">{% endaddtoblock %}
{% addtoblock "css" %}
{% extends "website/base.html" %} {% load sekizai_tags static %} {% block content %} {% addtoblock "css" strip %}<link
rel="stylesheet"
type="text/css"
href="{{STATIC_URL}}/css/portfolio.css"
media="screen, projection"
/>{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
type="text/css"
href="{{STATIC_URL}}/css/lib/isotope.css"
/>{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
type="text/css"
href="{{STATIC_URL}}/css/lib/animate.css"
/>{% endaddtoblock %} {% addtoblock "css" %}
<style>
.addressbook_entry {
box-shadow: 0px 0px 7px -1px rgb(214, 214, 214);
border: 2px solid rgb(217, 217, 217);
width: 360px !important;
float: left;
padding-top: 20px;
padding-left: 5px;
padding-bottom: 20px;
border-radius: 10px;
}
.addressbook_entry {
box-shadow: 0px 0px 7px -1px rgb(214, 214, 214);
border: 2px solid rgb(217, 217, 217);
width: 360px !important;
float: left;
padding-top: 20px;
padding-left: 5px;
padding-bottom: 20px;
border-radius: 10px;
}
.addressbook_entry .name {
color: rgb(83, 83, 83);
font-weight: normal;
font-style: italic;
font-size: 18px;
margin: 0px 0px 5px;
}
.addressbook_entry .name {
color: rgb(83, 83, 83);
font-weight: normal;
font-style: italic;
font-size: 18px;
margin: 0px 0px 5px;
}
.addressbook_entry td {
padding-right: 15px;
}
.addressbook_entry td {
padding-right: 15px;
}
.addressbook_entry .picture {
max-width: 55px;
float: left;
padding-left: 10px;
}
.addressbook_entry td.labelCell {
white-space: nowrap;
}
@media (max-width: 480px) {
.addressbook_entry {
font-size: 11px;
width: 265px !important;
}
.addressbook_entry .picture {
max-width: 55px;
float: left;
padding-left: 5px;
padding-right: 5px;
}
}
@media (max-width: 300px) {
.addressbook_entry .picture {
display: none;
}
.addressbook_entry {
width: 200px !important;
}
}
.addressbook_entry .picture {
max-width: 55px;
float: left;
padding-left: 10px;
}
.addressbook_entry td.labelCell {
white-space: nowrap;
}
@media (max-width: 480px) {
.addressbook_entry {
font-size: 11px;
width: 265px !important;
}
.addressbook_entry .picture {
max-width: 55px;
float: left;
padding-left: 5px;
padding-right: 5px;
}
}
@media (max-width: 300px) {
.addressbook_entry .picture {
display: none;
}
.addressbook_entry {
width: 200px !important;
}
}
</style>
{% endaddtoblock %}
{% addtoblock "js" strip %} <script src="{{STATIC_URL}}js/jquery.isotope.min.js"></script> {% endaddtoblock %}
{% addtoblock "js" %}
{% endaddtoblock %} {% addtoblock "js" strip %}
<script src="{{STATIC_URL}}/js/jquery.isotope.min.js"></script>
{% endaddtoblock %} {% addtoblock "js" %}
<script>
$(function(){
$(function () {
var $container = $("#gallery_container"),
$filters = $("#filters a");
var $container = $('#gallery_container'),
$filters = $("#filters a");
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.photo',
masonry: {
columnWidth: 102
}
});
$container.imagesLoaded(function () {
$container.isotope({
itemSelector: ".photo",
masonry: {
columnWidth: 102,
},
});
// filter items when filter link is clicked
$filters.click(function() {
$filters.removeClass("active");
$(this).addClass("active");
var selector = $(this).data('filter');
$container.isotope({ filter: selector });
return false;
});
});
</script>
// filter items when filter link is clicked
$filters.click(function () {
$filters.removeClass("active");
$(this).addClass("active");
var selector = $(this).data("filter");
$container.isotope({ filter: selector });
return false;
});
});
</script>
{% endaddtoblock %}
<div id="portfolio">
<div class="container">
<div class="section_header">
<h3>Adressbuch</h3>
<div class="container">
<div class="section_header">
<h3>Adressbuch</h3>
</div>
<div class="row">
<div class="span12">
<div id="filters_container">
<ul id="filters">
<li><a href="#" data-filter="*" class="active">Alle</a></li>
<li class="separator">/</li>
<li><a href="#" data-filter=".unterstimme">Unterstimmen</a></li>
<li class="separator">/</li>
<li><a href="#" data-filter=".oberstimme">Oberstimmen</a></li>
<li class="separator">/</li>
<li><a href="#" data-filter=".rest">Rest</a></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div id="gallery_container" >
{% for m in musicians %}
<div class="photo isotope-item addressbook_entry {% if m.isDeepBrass %} unterstimme {% elif m.isHighBrass %} oberstimme {% else %} rest {% endif %} ">
<div>
<img src="{{MEDIA_URL}}/user_images/{{m.user}}_thumb.png" class="img-circle picture">
</div>
<div class="name">
{{ m.user.first_name }} {{m.user.last_name }}
</div>
{% if not request.device.android %}
<table>
{% if m.street %} <tr><td class="labelCell"> Adresse </td><td>{{m.street}} </td>
<tr><td class="labelCell"> </td><td>{{m.zip_code}} {{m.city}}</td>{% endif %}
{% if m.birthday %} <tr><td class="labelCell"> Geburtstag: </td><td>{{m.birthday }} </td>{% endif %}
{% if m.phone_home %} <tr><td class="labelCell"> Telefon (Home): </td><td>{{m.phone_home }} </td>{% endif %}
{% if m.phone_mobile %}<tr><td class="labelCell"> Telefon (Mobil): </td><td>{{m.phone_mobile }} </td>{% endif %}
{% if m.phone_work %} <tr><td class="labelCell"> Telefon (Arbeit): </td><td>{{m.phone_work }} </td>{% endif %}
</table>
{% else %}
<table>
{% if m.street %} <tr><td class="labelCell"> Adresse </td><td>{{m.street}} </td>
<tr><td class="labelCell"> </td><td>{{m.zip_code}} {{m.city}}</td>{% endif %}
{% if m.birthday %} <tr><td class="labelCell"> Geburtstag: </td><td>{{m.birthday }} </td>{% endif %}
{% if m.phone_home %} <tr><td class="labelCell"> Telefon (Home): </td><td><a href="tel:{{m.phone_home }}"> {{m.phone_home }} </a> </td>{% endif %}
{% if m.phone_mobile %}<tr><td class="labelCell"> Telefon (Mobil): </td><td><a href="tel:{{m.phone_mobile }}"> {{m.phone_mobile }} </a> </td>{% endif %}
{% if m.phone_work %} <tr><td class="labelCell"> Telefon (Arbeit): </td><td><a href="tel:{{m.phone_work }}"> {{m.phone_work }} </a> </td>{% endif %}
</table>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div id="filters_container">
<ul id="filters">
<li>
<a href="#" data-filter="*" class="active">Alle</a>
</li>
<li class="separator">/</li>
<li>
<a href="#" data-filter=".unterstimme"
>Unterstimmen</a
>
</li>
<li class="separator">/</li>
<li>
<a href="#" data-filter=".oberstimme"
>Oberstimmen</a
>
</li>
<li class="separator">/</li>
<li><a href="#" data-filter=".rest">Rest</a></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div id="gallery_container">
{% for m in musicians %}
<div
class="photo isotope-item addressbook_entry {% if m.isDeepBrass %} unterstimme {% elif m.isHighBrass %} oberstimme {% else %} rest {% endif %}"
>
<div>
<img
src="{{MEDIA_URL}}/user_images/{{m.user}}_thumb.png"
class="img-circle picture"
/>
</div>
<div class="name">
{{ m.user.first_name }} {{m.user.last_name }}
</div>
{% if not request.device.android %}
<table>
{% if m.street %}
<tr>
<td class="labelCell">Adresse</td>
<td>{{m.street}}</td>
</tr>
<tr>
<td class="labelCell"></td>
<td>{{m.zip_code}} {{m.city}}</td>
{% endif %} {% if m.birthday %}
</tr>
<tr>
<td class="labelCell">Geburtstag:</td>
<td>{{m.birthday }}</td>
{% endif %} {% if m.phone_home %}
</tr>
<tr>
<td class="labelCell">Telefon (Home):</td>
<td>{{m.phone_home }}</td>
{% endif %} {% if m.phone_mobile %}
</tr>
<tr>
<td class="labelCell">Telefon (Mobil):</td>
<td>{{m.phone_mobile }}</td>
{% endif %} {% if m.phone_work %}
</tr>
<tr>
<td class="labelCell">Telefon (Arbeit):</td>
<td>{{m.phone_work }}</td>
{% endif %}
</tr>
</table>
{% else %}
<table>
{% if m.street %}
<tr>
<td class="labelCell">Adresse</td>
<td>{{m.street}}</td>
</tr>
<tr>
<td class="labelCell"></td>
<td>{{m.zip_code}} {{m.city}}</td>
{% endif %} {% if m.birthday %}
</tr>
<tr>
<td class="labelCell">Geburtstag:</td>
<td>{{m.birthday }}</td>
{% endif %} {% if m.phone_home %}
</tr>
<tr>
<td class="labelCell">Telefon (Home):</td>
<td>
<a href="tel:{{m.phone_home }}">
{{m.phone_home }}
</a>
</td>
{% endif %} {% if m.phone_mobile %}
</tr>
<tr>
<td class="labelCell">Telefon (Mobil):</td>
<td>
<a href="tel:{{m.phone_mobile }}">
{{m.phone_mobile }}
</a>
</td>
{% endif %} {% if m.phone_work %}
</tr>
<tr>
<td class="labelCell">Telefon (Arbeit):</td>
<td>
<a href="tel:{{m.phone_work }}">
{{m.phone_work }}
</a>
</td>
{% endif %}
</tr>
</table>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,101 +1,120 @@
{% extends "website/base.html" %}
{% extends "website/base.html" %} {% load sekizai_tags static %} {% block menu_contents %} {% endblock %} {% block content %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/lib/animate.css"
type="text/css"
media="screen, projection"
/>{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/sign-in.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %} {% addtoblock "js" strip %}
<script src="{{STATIC_URL}}/js/jquery.noty.js"></script>
{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/jquery.noty.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/noty_theme_default.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %}
<!-- For Autocompete -->
{% addtoblock "js" strip %}
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
{% endaddtoblock %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/jquery-ui-1.8.21.custom.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %}
{% load sekizai_tags staticfiles %}
<!-- Notifications -->
{% addtoblock "js" %}
<script>
$(document).ready(function () {
$("#loginform").submit(function (e) {
$.ajax({
type: "POST",
url: "",
data: $("#loginform").serialize(),
dataType: "json",
success: function (data) {
if (data["err"]) {
noty({
text: data["err"],
layout: "top",
type: "error",
});
}
if (data["redirect"]) {
window.location.href = data["redirect"];
}
},
error: function (jqXHR, text1, text2) {
console.log(jqXHR);
console.log(text1);
console.log(text2);
},
});
e.preventDefault();
});
{% block menu_contents %}
{% endblock %}
$.get("/musicians/login/usernames", function (data) {
$("#username").autocomplete({ source: data });
});
});
</script>
{% endaddtoblock %}
<div id="sign_in">
<div class="container">
<div class="row">
<div class="span12 header">
<h4>Login zum internen Bereich</h4>
<p>Hier dürfen nur Ensemble Mitglieder rein...</p>
</div>
<div class="span12 footer" action="index.html" method="post">
<form id="loginform">
{% csrf_token %}
<input
name="username"
type="text"
placeholder="Benutzername"
id="username"
/>
<input
name="password"
type="password"
placeholder="Passwort"
/>
<input name="next" type="hidden" value="{{next}}" />
<input type="submit" placeholder="OK" value="einloggen" />
</form>
</div>
{% block content %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/lib/animate.css" type="text/css" media="screen, projection">{% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/sign-in.css" type="text/css" media="screen" /> {% endaddtoblock %}
{% addtoblock "js" strip %} <script src="{{STATIC_URL}}js/jquery.noty.js"></script> {% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/jquery.noty.css" type="text/css" media="screen" /> {% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/noty_theme_default.css" type="text/css" media="screen" /> {% endaddtoblock %}
<!-- for auto complete -->
{% addtoblock "js" strip %} <script src="{{STATIC_URL}}js/jquery-ui-1.12.1.min.js"></script> {% endaddtoblock %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/jquery-ui-1.12.1.min.css" type="text/css" media="screen" /> {% endaddtoblock %}
<!-- Notifications -->
{% addtoblock "js" %}
<script>
$(document).ready(function(){
$('#loginform').submit(function(e){
$.ajax({
type:"POST",
url:"",
data:$('#loginform').serialize(),
dataType: "json",
success: function( data )
{
if ( data['err'] ) {
noty ( { "text": data['err'],"layout":"top","type":"error" } )
}
if ( data['redirect']) {
window.location.href = data['redirect'];
}
},
error: function( jqXHR, text1, text2 ) {
console.log( jqXHR );
console.log( text1 );
console.log( text2 );
}
});
e.preventDefault();
});
$.get( "/musicians/login/usernames", function( data ) {
$("#username").autocomplete( { source: data } );
});
});
</script>
{% endaddtoblock %}
<div id="sign_in">
<div class="container">
<div class="row">
<div class="span12 header">
<h4>Login zum internen Bereich</h4>
<p>Hier dürfen nur Ensemble Mitglieder rein... </p>
<div class="span12 proof">
<div class="span6 remember">
<label class="checkbox">
<input id="remember" type="checkbox" /> Eingeloggt
bleiben
</label>
</div>
<div class="span12 footer" action="index.html" method="post">
<form id="loginform">
{% csrf_token %}
<input name="username" type="text" placeholder="Benutzername" id="username">
<input name="password" type="password" placeholder="Passwort">
<input name="next" type="hidden" value="{{next}}" >
<input type="submit" placeholder="OK" value="einloggen">
</form>
</div>
<div class="span12 proof">
<div class="span6 remember">
<label class="checkbox">
<input id="remember" type="checkbox"> Eingeloggt bleiben
</label>
</div>
<!--
<!--
<div class="span3 dosnt">
<a href="reset.html">Passwort vergessen?</a>
</div> -->
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,12 +1,14 @@
from django.conf.urls import url
from django.urls import path
import musicians.views
from . import views
app_name = "musicians"
urlpatterns = [
url(r'^$', musicians.views.addressbook),
url(r'^profile$', musicians.views.own_profile),
url(r'^changePassword/$', musicians.views.change_password),
url(r'^login/$', musicians.views.login_view),
url(r'^login/usernames$', musicians.views.userlistForAutocompletion),
url(r'^logout/$', musicians.views.logout_view),
path("", views.addressbook, name="addressbook"),
path("profile/", views.own_profile, name="profile"),
path("changePassword/", views.change_password, name="change_password"),
path("login/", views.login_view, name="login"),
path("login/usernames/", views.userlistForAutocompletion, name="usernames"),
path("logout/", views.logout_view, name="logout"),
]

View File

@@ -1,10 +1,17 @@
from django.views.generic.edit import UpdateView
from django.views.generic import ListView
from musicians.models import Musician
import json
from datetime import timedelta
from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.views import PasswordChangeView
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse_lazy
from django.views.generic import ListView
from django.views.generic.edit import UpdateView
from .models import Musician
class MusicianList(ListView):
@@ -14,32 +21,49 @@ class MusicianList(ListView):
class UserEditForm(forms.ModelForm):
email = forms.EmailField()
def __init__(self, *args, **kw):
if 'instance' in kw.keys():
user = kw['instance'].user
initVals = {'email': user.email}
if not 'initial' in kw.keys():
kw['initial'] = initVals
else:
kw['initial'].update(initVals)
super(UserEditForm, self).__init__(*args, **kw)
self.fields.keyOrder.remove('email')
self.fields.keyOrder.insert(2, 'email')
def save(self):
if self.is_valid():
super(UserEditForm, self).save()
self.instance.user.email = self.cleaned_data['email']
self.instance.user.save()
class Meta:
model = Musician
exclude = ['user', 'image', 'small_image', 'instrument', 'position', 'public_description']
# fields = '__all__'
exclude = [
"user",
"image",
"small_image",
"instrument",
"position",
"public_description",
]
def __init__(self, *args, **kw):
if "instance" in kw:
user = kw["instance"].user
initVals = {"email": user.email}
if "initial" not in kw:
kw["initial"] = initVals
else:
kw["initial"].update(initVals)
super().__init__(*args, **kw)
# Reorder fields to put email near the top
if "email" in self.fields:
email_field = self.fields.pop("email")
new_fields = {}
field_names = list(self.fields.keys())
# Insert email at position 2 (after first two fields)
for i, name in enumerate(field_names):
if i == 2:
new_fields["email"] = email_field
new_fields[name] = self.fields[name]
if "email" not in new_fields:
new_fields["email"] = email_field
self.fields = new_fields
def save(self, commit=True):
if self.is_valid():
instance = super().save(commit=commit)
self.instance.user.email = self.cleaned_data["email"]
self.instance.user.save()
return instance
return None
def own_profile(request):
@@ -49,30 +73,31 @@ def own_profile(request):
def user_edit(request, username):
musician = get_object_or_404(Musician, user__username=username)
if request.method == 'POST': # If the form has been submitted...
form = UserEditForm(request.POST) # A form bound to the POST data
form.instance = musician
if form.is_valid(): # All validation rules pass
if request.method == "POST":
form = UserEditForm(request.POST, instance=musician)
if form.is_valid():
form.save()
return HttpResponseRedirect('/') # Redirect after POST
return HttpResponseRedirect("/")
else:
form = UserEditForm(instance=musician)
return render(request, 'musicians/musician_edit.html', {'form': form, 'musician': musician})
return render(
request, "musicians/musician_edit.html", {"form": form, "musician": musician}
)
class MusicianUpdate(UpdateView):
model = Musician
# fields = []
template_name = "musicians/musician_edit.html"
success_url = '/books/'
success_url = "/books/"
fields = "__all__"
def addressbook(request):
context = dict()
context['musicians'] = Musician.objects.all().order_by('user__first_name')
context = {}
context["musicians"] = Musician.objects.all().order_by("user__first_name")
return render(request, 'musicians/addressbook.html', context)
return render(request, "musicians/addressbook.html", context)
############################################################################################################
@@ -80,17 +105,13 @@ def addressbook(request):
############################################################################################################
from django.contrib.auth.views import PasswordChangeView
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect
from django.http import HttpResponse
import json
from django.contrib.auth.models import User
from datetime import timedelta
class ChangePasswordView(PasswordChangeView):
template_name = "musicians/change_password.html"
success_url = reverse_lazy("website:home")
def change_password(request):
return PasswordChangeView.as_view(request, "musicians/change_password.html", post_change_redirect="/")
return ChangePasswordView.as_view()(request)
def logout_view(request):
@@ -100,47 +121,44 @@ def logout_view(request):
def userlistForAutocompletion(request):
result = [u.username for u in User.objects.all()]
return HttpResponse(json.dumps(result), content_type='application/json')
return HttpResponse(json.dumps(result), content_type="application/json")
def login_view(request):
if request.method == 'POST': # If the form has been submitted...
raise_first_letter = lambda s: s[:1].upper() + s[1:] if s else ''
username = raise_first_letter(request.POST['username'])
password = request.POST['password']
user = authenticate(username=username, password=password)
result = dict()
result['err'] = ""
if request.method == "POST":
raiseFirstLetter = lambda s: s[:1].upper() + s[1:] if s else ""
username = raiseFirstLetter(request.POST.get("username", ""))
password = request.POST.get("password", "")
user = authenticate(request, username=username, password=password)
result = {}
result["err"] = ""
if user is not None:
if user.is_active:
if not request.POST.get('remember', None):
if not request.POST.get("remember", None):
# Expire in one year
request.session.set_expiry(timedelta(weeks=52).seconds)
request.session.set_expiry(timedelta(weeks=52))
else:
# Expire on browser close
request.session.set_expiry(0)
login(request, user)
result['redirect'] = "/"
print("Setting Redirect")
if 'next' in request.POST:
result['redirect'] = request.POST["next"]
print("Using " + request.POST["next"])
result["redirect"] = "/"
if "next" in request.POST:
result["redirect"] = request.POST["next"]
else:
result['err'] = "Dein Account wurde deaktiviert."
# Return a 'disabled account' error message
result["err"] = "Dein Account wurde deaktiviert."
else:
result['err'] = "Falscher Benutzername oder falsches Kennwort."
result["err"] = "Falscher Benutzername oder falsches Kennwort."
return HttpResponse(json.dumps(result), content_type='application/json')
return HttpResponse(json.dumps(result), content_type="application/json")
else:
# Check if user already logged in
if request.user.is_authenticated:
return redirect("/")
if 'next' in request.GET:
nextPage = request.GET['next']
if "next" in request.GET:
nextPage = request.GET["next"]
else:
nextPage = "/"
return render(request, 'musicians/login.html', {'next': nextPage})
return render(request, "musicians/login.html", {"next": nextPage})