Contest Entry class management foo
This commit is contained in:
parent
97b43db428
commit
625bd0f072
2
TODO
2
TODO
|
@ -4,7 +4,6 @@
|
||||||
- register users still has "reference" labels, make form better
|
- register users still has "reference" labels, make form better
|
||||||
- contest log add deadline
|
- contest log add deadline
|
||||||
- cbr parser zum hochladen
|
- cbr parser zum hochladen
|
||||||
- contest teilnahme klassen
|
|
||||||
- "Please register with your (uppercase) Callsign as Usernames. For DN-Calls, /[A-Z] is allowed." gibt es wohl noch wo
|
- "Please register with your (uppercase) Callsign as Usernames. For DN-Calls, /[A-Z] is allowed." gibt es wohl noch wo
|
||||||
|
|
||||||
(Partially) Done
|
(Partially) Done
|
||||||
|
@ -24,6 +23,7 @@
|
||||||
- beim qso log kann noch vorne die uhrzeit dran
|
- beim qso log kann noch vorne die uhrzeit dran
|
||||||
- bastla will anderen regex
|
- bastla will anderen regex
|
||||||
- align log button with log
|
- align log button with log
|
||||||
|
- contest teilnahme klassen
|
||||||
|
|
||||||
Glaube nich, dass ich das mache
|
Glaube nich, dass ich das mache
|
||||||
- call dupe validation könnte ins model wandern
|
- call dupe validation könnte ins model wandern
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import Frequency, Band, Reference, QSO, User, Contest, ShadowCall
|
from .models import Frequency, Band, Reference, QSO, User, Contest, ShadowCall, EntryCategory
|
||||||
|
|
||||||
admin.site.register(User)
|
admin.site.register(User)
|
||||||
admin.site.register(QSO)
|
admin.site.register(QSO)
|
||||||
|
@ -8,3 +8,4 @@ admin.site.register(Frequency)
|
||||||
admin.site.register(Reference)
|
admin.site.register(Reference)
|
||||||
admin.site.register(Contest)
|
admin.site.register(Contest)
|
||||||
admin.site.register(ShadowCall)
|
admin.site.register(ShadowCall)
|
||||||
|
admin.site.register(EntryCategory)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from crispy_forms.helper import FormHelper
|
||||||
from crispy_forms.layout import Submit, Layout
|
from crispy_forms.layout import Submit, Layout
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from .models import User, Reference, QSO, ShadowCall
|
from .models import User, Reference, QSO, ShadowCall, EntryCategory
|
||||||
from .validators import CallUsernameValidator, CallLogValidator
|
from .validators import CallUsernameValidator, CallLogValidator
|
||||||
|
|
||||||
class CustomUserCreationForm(UserCreationForm):
|
class CustomUserCreationForm(UserCreationForm):
|
||||||
|
@ -37,6 +37,19 @@ class UpdateRefForm(forms.Form):
|
||||||
if not existingRef and not newRefName:
|
if not existingRef and not newRefName:
|
||||||
raise forms.ValidationError("Select either an existing ref or create a new one!")
|
raise forms.ValidationError("Select either an existing ref or create a new one!")
|
||||||
|
|
||||||
|
class UpdateCategoryForm(forms.Form):
|
||||||
|
entry = forms.ModelChoiceField(label="Entry category", queryset=EntryCategory.objects.all())
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(UpdateCategoryForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_class = "form-inline "
|
||||||
|
self.helper.form_style = 'inline'
|
||||||
|
self.helper.field_template = "bootstrap3/layout/inline_field.html"
|
||||||
|
self.helper.action = reverse("profile")
|
||||||
|
self.helper.add_input(Submit('submit', 'Set category'))
|
||||||
|
self.helper.layout = Layout('entry')
|
||||||
|
|
||||||
class QSOForm(forms.ModelForm):
|
class QSOForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = QSO
|
model = QSO
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-26 18:52
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0011_auto_20170125_0126'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EntryCategory',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=40, unique=True)),
|
||||||
|
('description', models.TextField(blank=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='cat',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contest.EntryCategory'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2017-01-26 19:09
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0012_auto_20170126_1852'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='entrycategory',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64, unique=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -24,6 +24,13 @@ class Reference(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
class EntryCategory(models.Model):
|
||||||
|
name = models.CharField(max_length=64, unique=True)
|
||||||
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
class ShadowCall(models.Model):
|
class ShadowCall(models.Model):
|
||||||
username = models.CharField(max_length=20, unique=True, db_index=True, validators=[CallUsernameValidator()])
|
username = models.CharField(max_length=20, unique=True, db_index=True, validators=[CallUsernameValidator()])
|
||||||
ref = models.ForeignKey(Reference, models.SET_NULL,null=True, blank=True)
|
ref = models.ForeignKey(Reference, models.SET_NULL,null=True, blank=True)
|
||||||
|
@ -32,7 +39,8 @@ class ShadowCall(models.Model):
|
||||||
return self.username
|
return self.username
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
ref = models.ForeignKey(Reference, models.SET_NULL,null=True, blank=True)
|
ref = models.ForeignKey(Reference, models.SET_NULL, null=True, blank=True)
|
||||||
|
cat = models.ForeignKey(EntryCategory, models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(User, self).__init__(*args, **kwargs)
|
super(User, self).__init__(*args, **kwargs)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from .models import User, Contest, Frequency, Reference, QSO, ShadowCall
|
from .models import User, Contest, Frequency, Reference, QSO, ShadowCall
|
||||||
from .forms import UpdateRefForm, QSOForm, QSOFormWithTime, CustomUserCreationForm, ShadowCallAddForm
|
from .forms import UpdateRefForm, QSOForm, QSOFormWithTime, CustomUserCreationForm, ShadowCallAddForm, UpdateCategoryForm
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
|
@ -208,13 +208,30 @@ def register(request):
|
||||||
@login_required
|
@login_required
|
||||||
def profile(request):
|
def profile(request):
|
||||||
pwForm = None
|
pwForm = None
|
||||||
|
catForm = None
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
if request.POST.get("submit", None) == "pwchange":
|
||||||
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
pwForm = PasswordChangeForm(user=request.user, data=request.POST)
|
||||||
if pwForm.is_valid():
|
if pwForm.is_valid():
|
||||||
pwForm.save()
|
pwForm.save()
|
||||||
auth_login(request, pwForm.user)
|
auth_login(request, pwForm.user)
|
||||||
messages.success(request, "Password changed")
|
messages.success(request, "Password changed")
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse("profile"))
|
||||||
else:
|
else:
|
||||||
|
catForm = UpdateCategoryForm(data=request.POST)
|
||||||
|
if catForm.is_valid():
|
||||||
|
request.user.cat = catForm.cleaned_data["entry"]
|
||||||
|
request.user.save()
|
||||||
|
messages.success(request, "Entry category set")
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse("profile"))
|
||||||
|
|
||||||
|
if not pwForm:
|
||||||
pwForm = PasswordChangeForm(user=request.user)
|
pwForm = PasswordChangeForm(user=request.user)
|
||||||
|
|
||||||
return render(request, 'registration/profile.html', {"pwForm": pwForm})
|
if not catForm:
|
||||||
|
catForm = UpdateCategoryForm(initial={'entry': request.user.cat})
|
||||||
|
|
||||||
|
return render(request, 'registration/profile.html', {"pwForm": pwForm, "catForm": catForm})
|
||||||
|
|
|
@ -40,15 +40,28 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not user.cat %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="panel panel-warning">
|
||||||
|
<div class="panel-heading">You don't have a category!</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p>
|
||||||
|
You don't have an <strong>entry category</strong>! Please set one in your <a href="{% url "profile" %}">profile</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<div class="panel-heading">You are staff!</div>
|
<div class="panel-heading">You are staff!</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p>
|
|
||||||
<p>Hey, you are <strong>staff</strong>. Do you want to start <a href="{% url "contest:registerRefs" %}">registering people</a>?</p>
|
<p>Hey, you are <strong>staff</strong>. Do you want to start <a href="{% url "contest:registerRefs" %}">registering people</a>?</p>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,13 +9,19 @@
|
||||||
<div class="panel-heading">User Info</div>
|
<div class="panel-heading">User Info</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">User</label>
|
<label class="control-label">User <span class="glyphicon glyphicon-ok-sign text-success"></span></label>
|
||||||
<p class="form-control-static">{{ user }}</p>
|
<p class="form-control-static">{{ user }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Exchange</label>
|
<label class="control-label">Exchange <span class="glyphicon {% if user.ref %}glyphicon-ok-sign text-success{% else %}glyphicon-remove-sign text-danger{% endif %}"></span></label>
|
||||||
<p class="form-control-static">{{ user.ref|default:"Not registered" }}</p>
|
<p class="form-control-static">{{ user.ref|default:"Not registered" }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label">Contest Entry <span class="glyphicon {% if user.cat %}glyphicon-ok-sign text-success{% else %}glyphicon-remove-sign text-danger{% endif %}"></span></label>
|
||||||
|
<p>
|
||||||
|
{% crispy catForm %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,7 +32,7 @@
|
||||||
<form method="POST" action="{% url "profile" %}">
|
<form method="POST" action="{% url "profile" %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ pwForm|crispy }}
|
{{ pwForm|crispy }}
|
||||||
<button type="submit" class="btn btn-primary" name="form" value="pwchange">Change Password</button>
|
<button type="submit" class="btn btn-primary" name="submit" value="pwchange">Change Password</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue