Merge branch 'develop' into feature-pep8-fixes
This commit is contained in:
@@ -48,10 +48,10 @@ def on_message(client, userdata, msg):
|
|||||||
|
|
||||||
def on_disconnect(client, userdata, rc):
|
def on_disconnect(client, userdata, rc):
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
print("Unexpected disconnection.")
|
logging.warning("MQTT unexpectedly disconnected.")
|
||||||
else:
|
else:
|
||||||
client.loop_stop(force=False)
|
client.loop_stop(force=False)
|
||||||
print("Disconnected")
|
logging.warning("MQTT disconnected.")
|
||||||
|
|
||||||
|
|
||||||
def get_latest():
|
def get_latest():
|
||||||
|
|||||||
@@ -184,8 +184,6 @@ def create_image_item(request, *args, **kwargs):
|
|||||||
def create_video_item(request, *args, **kwargs):
|
def create_video_item(request, *args, **kwargs):
|
||||||
"""Create video Infoscreen item."""
|
"""Create video Infoscreen item."""
|
||||||
form = UploadFileForm(request.POST, request.FILES)
|
form = UploadFileForm(request.POST, request.FILES)
|
||||||
print(form.errors)
|
|
||||||
print("hurdurr")
|
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return HttpResponseBadRequest('{"status": "failure",'
|
return HttpResponseBadRequest('{"status": "failure",'
|
||||||
'"error": "invalid data supplied"}')
|
'"error": "invalid data supplied"}')
|
||||||
|
|||||||
+70
-1
@@ -5,6 +5,15 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from members.models import Member, Payment, Request
|
from members.models import Member, Payment, Request
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class CSVValidationError(Exception):
|
||||||
|
def __init__(self, form_errors):
|
||||||
|
self.form_errors = form_errors
|
||||||
|
|
||||||
|
|
||||||
class MemberForm(forms.ModelForm):
|
class MemberForm(forms.ModelForm):
|
||||||
"""Member model form."""
|
"""Member model form."""
|
||||||
@@ -13,7 +22,67 @@ class MemberForm(forms.ModelForm):
|
|||||||
"""Meta for Member model form."""
|
"""Meta for Member model form."""
|
||||||
|
|
||||||
model = Member
|
model = Member
|
||||||
fields = ['first_name', 'last_name', 'email', 'AYY', 'jas', 'POR']
|
fields = ['first_name', 'last_name', 'email', 'POR', 'AYY', 'jas']
|
||||||
|
|
||||||
|
class ImportResult:
|
||||||
|
def __init__(self, members, payments):
|
||||||
|
self.members = members
|
||||||
|
self.payments = payments
|
||||||
|
|
||||||
|
def clean_email(self):
|
||||||
|
email = self.cleaned_data['email']
|
||||||
|
|
||||||
|
if Member.objects.filter(email=email).exists():
|
||||||
|
raise forms.ValidationError('Member with email "{}" already exists.'.format(email), code='exists')
|
||||||
|
|
||||||
|
return email
|
||||||
|
|
||||||
|
def clean_jas(self):
|
||||||
|
return bool(int(self.data['jas']))
|
||||||
|
|
||||||
|
def clean_AYY(self):
|
||||||
|
return bool(int(self.data['AYY']))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def csv_to_models(data, payment_source='AYY'):
|
||||||
|
clean_data = data.strip().split('\n')
|
||||||
|
clean_data = [row.rstrip(',') for row in clean_data]
|
||||||
|
csv_reader = csv.DictReader(clean_data, fieldnames=MemberForm.Meta.fields)
|
||||||
|
|
||||||
|
members = []
|
||||||
|
payments = []
|
||||||
|
for line in csv_reader:
|
||||||
|
for key, value in line.items():
|
||||||
|
line[key] = value.strip()
|
||||||
|
|
||||||
|
email = line['email']
|
||||||
|
member_exists = False
|
||||||
|
if Member.objects.filter(email=email).exists():
|
||||||
|
member_exists = True
|
||||||
|
|
||||||
|
if not member_exists:
|
||||||
|
form = MemberForm(line)
|
||||||
|
if not form.is_valid():
|
||||||
|
raise CSVValidationError(form.errors)
|
||||||
|
|
||||||
|
model = form.save(commit=False)
|
||||||
|
members.append(model)
|
||||||
|
|
||||||
|
else:
|
||||||
|
member = Member.objects.get(email=email)
|
||||||
|
payment_data = {
|
||||||
|
'source': payment_source,
|
||||||
|
'member': member.id,
|
||||||
|
'date': datetime.datetime.now(),
|
||||||
|
}
|
||||||
|
form = PaymentForm(payment_data)
|
||||||
|
if not form.is_valid():
|
||||||
|
raise CSVValidationError(form.errors)
|
||||||
|
|
||||||
|
model = form.save(commit=False)
|
||||||
|
payments.append(model)
|
||||||
|
|
||||||
|
return MemberForm.ImportResult(members, payments)
|
||||||
|
|
||||||
|
|
||||||
class PaymentForm(forms.ModelForm):
|
class PaymentForm(forms.ModelForm):
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2017-09-20 11:57
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('members', '0013_auto_20170601_1822'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(max_length=254, unique=True, verbose_name='Email'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='request',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(max_length=254, unique=True, verbose_name='Email'),
|
||||||
|
),
|
||||||
|
]
|
||||||
+1
-3
@@ -13,7 +13,7 @@ class BaseMember(models.Model):
|
|||||||
|
|
||||||
first_name = models.CharField(_("First name"), max_length=127)
|
first_name = models.CharField(_("First name"), max_length=127)
|
||||||
last_name = models.CharField(_("Last name"), max_length=127)
|
last_name = models.CharField(_("Last name"), max_length=127)
|
||||||
email = models.EmailField(_("Email"))
|
email = models.EmailField(_("Email"), unique=True)
|
||||||
POR = models.CharField(_("Place of residence"),
|
POR = models.CharField(_("Place of residence"),
|
||||||
max_length=255) # place of residence
|
max_length=255) # place of residence
|
||||||
AYY = models.BooleanField(_("AYY"), default=False)
|
AYY = models.BooleanField(_("AYY"), default=False)
|
||||||
@@ -30,8 +30,6 @@ class BaseMember(models.Model):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_csv(data):
|
def from_csv(data):
|
||||||
"""Construct member model from csv data."""
|
|
||||||
print("Imported CSV data: {}".format(data))
|
|
||||||
clean_data = data.strip().split('\n')
|
clean_data = data.strip().split('\n')
|
||||||
csv_reader = csv.reader(clean_data)
|
csv_reader = csv.reader(clean_data)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
{{ error }}
|
{{ error|safe }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button onclick="window.history.back();" class="btn btn-primary">{% trans "Back" %}</button>
|
<button onclick="window.history.back();" class="btn btn-primary">{% trans "Back" %}</button>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h3> Lisää useampi jäsen </h3>
|
<h3>{% trans "Add many members" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -25,9 +25,18 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<form name="memberTextForm" action="/members/import_csv" method="POST">{% csrf_token %}
|
<form name="memberTextForm" action="/members/import_csv" method="POST">{% csrf_token %}
|
||||||
<div>
|
<div class="form-group">
|
||||||
|
<label>{% trans "Data" %}</label>
|
||||||
<textarea name="textfield" class="form-control large-textarea" placeholder="Teemu, Teekkari, teemu.teekkari@notmail.dom, Otaniemi, 0, 0"></textarea>
|
<textarea name="textfield" class="form-control large-textarea" placeholder="Teemu, Teekkari, teemu.teekkari@notmail.dom, Otaniemi, 0, 0"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{% trans "Payment source" %}</label>
|
||||||
|
<select name="payment_source" class="form-control">
|
||||||
|
<option value="AYY">{% trans "AYY" %}</option>
|
||||||
|
<option value="bank_transfer">{% trans "Bank transfer" %}</option>
|
||||||
|
<option value="cash">{% trans "Cash payment" %}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" class="btn btn-primary">{% trans "Send" %}</button>
|
<button type="submit" class="btn btn-primary">{% trans "Send" %}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{% extends "members_base.html" %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h3>{% trans "Confirm adding these entries?" %}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{% trans "Members" %}</label>
|
||||||
|
{{ members|safe }}
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{% trans "Payments" %}</label>
|
||||||
|
{{ payments|safe }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form name="memberTextForm" action="/members/add_many_confirm" method="POST">{% csrf_token %}
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="btn btn-primary">{% trans "Send" %}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
{% extends "members_base.html" %}
|
|
||||||
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<h3>{% trans "Conflicting member entries" %}</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p>{% blocktrans %}Found conflicting member entries. Choose how to handle the problematic data.{% endblocktrans %}</p>
|
|
||||||
|
|
||||||
{% for conflict in conflicts %}
|
|
||||||
<div class="conflict-row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<table class="table readonly table-conflict bg-info" >
|
|
||||||
{{ conflict.first_member_form }}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<table class="table readonly table-conflict bg-info" >
|
|
||||||
{{ conflict.second_member_form }}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<form action="/members/resolve_conflict" method="POST">{% csrf_token %}
|
|
||||||
<p>{% blocktrans %}Which one has the correct information for this member?{% endblocktrans %}</p>
|
|
||||||
<input type="hidden" name="id" value="{{ conflict.id }}">
|
|
||||||
<button type="submit" name="action" value="first" class="btn btn-primary">{% trans "Accept first and remove second" %}</button>
|
|
||||||
<button type="submit" name="action" value="second" class="btn btn-primary">{% trans "Accept second and remove first" %}</button>
|
|
||||||
<button type="submit" name="action" value="both" class="btn btn-primary">{% trans "Accept both as two members" %}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
|
||||||
+4
-8
@@ -18,8 +18,7 @@ from members.views import member_update
|
|||||||
from members.views import member_delete_confirm
|
from members.views import member_delete_confirm
|
||||||
from members.views import member_delete
|
from members.views import member_delete
|
||||||
from members.views import payment_list
|
from members.views import payment_list
|
||||||
from members.views import member_duplicates
|
from members.views import add_many_confirm
|
||||||
from members.views import resolve_conflict
|
|
||||||
|
|
||||||
# rest api
|
# rest api
|
||||||
from members.views import MemberDetail
|
from members.views import MemberDetail
|
||||||
@@ -93,6 +92,9 @@ urlpatterns = [
|
|||||||
# delete confirmation view
|
# delete confirmation view
|
||||||
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
url(r'^delete_payment_confirm/(?P<index>\d+)$', payment_delete_confirm),
|
||||||
|
|
||||||
|
# post endpoint for confirming multiple entries
|
||||||
|
url(r'^add_many_confirm$', add_many_confirm),
|
||||||
|
|
||||||
# settings page
|
# settings page
|
||||||
url(r'^settings$', settings_page),
|
url(r'^settings$', settings_page),
|
||||||
|
|
||||||
@@ -108,10 +110,4 @@ urlpatterns = [
|
|||||||
# rest api url
|
# rest api url
|
||||||
url(r'^api/members/(?P<pk>\d+)$', MemberDetail.as_view()),
|
url(r'^api/members/(?P<pk>\d+)$', MemberDetail.as_view()),
|
||||||
|
|
||||||
# member duplicate resolution view
|
|
||||||
url(r'^duplicates$', member_duplicates),
|
|
||||||
|
|
||||||
# post target for resolving a conflict
|
|
||||||
url(r'^resolve_conflict$', resolve_conflict)
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
+59
-90
@@ -8,6 +8,7 @@ from django.http import HttpResponse, HttpResponseRedirect
|
|||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.forms.models import model_to_dict
|
||||||
|
|
||||||
# Email validation
|
# Email validation
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
@@ -27,13 +28,18 @@ import requests
|
|||||||
import logging
|
import logging
|
||||||
import html
|
import html
|
||||||
import csv
|
import csv
|
||||||
|
import pickle
|
||||||
from smtplib import SMTPAuthenticationError
|
from smtplib import SMTPAuthenticationError
|
||||||
|
|
||||||
from members.models import Member, Request, Payment, MemberConflict
|
from members.models import Member, Request, Payment, MemberConflict
|
||||||
from members.forms import MemberForm, PaymentForm, ApplicationForm
|
from members.forms import MemberForm, PaymentForm, ApplicationForm, CSVValidationError
|
||||||
from members.tables import MemberTable, PaymentTable, RequestTable
|
from members.tables import MemberTable, PaymentTable, RequestTable
|
||||||
|
|
||||||
|
|
||||||
|
def error_view(request, message):
|
||||||
|
return render(request, 'error.html', {'error': str(message)})
|
||||||
|
|
||||||
|
|
||||||
def validate_recaptcha(response):
|
def validate_recaptcha(response):
|
||||||
"""
|
"""
|
||||||
Recaptcha is used in member applications.
|
Recaptcha is used in member applications.
|
||||||
@@ -518,23 +524,63 @@ def import_csv(request, *args, **kwargs):
|
|||||||
"""Get csv data imported to page and create members based on that."""
|
"""Get csv data imported to page and create members based on that."""
|
||||||
try:
|
try:
|
||||||
data = request.POST['textfield']
|
data = request.POST['textfield']
|
||||||
|
payment_source = request.POST['payment_source']
|
||||||
except:
|
except:
|
||||||
return render(request,
|
return render(request,
|
||||||
'error.html',
|
'error.html',
|
||||||
{'error': _('Missing "textfield" POST request field')})
|
{'error': _('Missing "textfield" POST request field')})
|
||||||
|
|
||||||
success = Member.from_csv(data)
|
try:
|
||||||
if success:
|
result = MemberForm.csv_to_models(data, payment_source=payment_source)
|
||||||
logging.info('Imported CSV data:\n'.format(data))
|
except CSVValidationError as ex:
|
||||||
notification = "{}.".format(
|
logging.exception('Model validation error')
|
||||||
_("Successfully imported multiple members"))
|
return error_view(request, ex.form_errors)
|
||||||
return HttpResponseRedirect(
|
except Exception as ex:
|
||||||
'/members/list?notification={}'
|
logging.exception('Other error in CSV import')
|
||||||
.format(html.escape(notification)))
|
return error_view(request, ex)
|
||||||
else:
|
|
||||||
return render(request,
|
member_table = MemberTable(result.members,
|
||||||
'error.html',
|
request=request,
|
||||||
{'error': _('Failed to import members')})
|
exclude=['id', 'options'],
|
||||||
|
attrs={'class': 'table table-bordered table-hover'})
|
||||||
|
|
||||||
|
member_table_html = convert_table_to_html(member_table, request)
|
||||||
|
|
||||||
|
payment_table = PaymentTable(result.payments,
|
||||||
|
request=request,
|
||||||
|
exclude=['id', 'options'],
|
||||||
|
attrs={'class': 'table table-bordered table-hover'})
|
||||||
|
|
||||||
|
payment_table_html = convert_table_to_html(payment_table, request)
|
||||||
|
|
||||||
|
request.session['models'] = result
|
||||||
|
context = {
|
||||||
|
'members': member_table_html,
|
||||||
|
'payments': payment_table_html
|
||||||
|
}
|
||||||
|
return render(request, 'member_add_many_confirm.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
@ensure_csrf_cookie
|
||||||
|
@require_http_methods(["POST"])
|
||||||
|
@permission_required('members.change_member', login_url='/login')
|
||||||
|
def add_many_confirm(request, *args, **kwargs):
|
||||||
|
models = request.session['models']
|
||||||
|
|
||||||
|
try:
|
||||||
|
members, payments = models.members, models.payments
|
||||||
|
for member in members:
|
||||||
|
member.save()
|
||||||
|
|
||||||
|
for payment in payments:
|
||||||
|
payment.save()
|
||||||
|
|
||||||
|
msg = "Successfully imported {} members and {} payments."
|
||||||
|
notification = _(msg).format(len(members), len(payments))
|
||||||
|
return HttpResponseRedirect('/members/list?notification={}'.format(html.escape(notification)))
|
||||||
|
except Exception as ex:
|
||||||
|
logging.exception('Failed to save models after "add many."')
|
||||||
|
return error_view(request, _('Failed to import members'))
|
||||||
|
|
||||||
|
|
||||||
@ensure_csrf_cookie
|
@ensure_csrf_cookie
|
||||||
@@ -558,62 +604,6 @@ def export_csv(request, *args, **kwargs):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@ensure_csrf_cookie
|
|
||||||
@require_http_methods(["GET"])
|
|
||||||
@permission_required('members.change_member', login_url='/login')
|
|
||||||
def member_duplicates(request, *args, **kwargs):
|
|
||||||
"""Check for duplicate members."""
|
|
||||||
conflicts = MemberConflict.objects.all()
|
|
||||||
context = {
|
|
||||||
'conflicts': conflicts
|
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, 'member_duplicates.html', context)
|
|
||||||
|
|
||||||
|
|
||||||
@ensure_csrf_cookie
|
|
||||||
@require_http_methods(["POST"])
|
|
||||||
@permission_required('members.change_member', login_url='/login')
|
|
||||||
def resolve_conflict(request, *args, **kwargs):
|
|
||||||
"""Resolve duplicate member conflict."""
|
|
||||||
action = request.POST.get('action', None)
|
|
||||||
if action not in ['first', 'second', 'both']:
|
|
||||||
return render(request,
|
|
||||||
'error.html',
|
|
||||||
{'error': '{}: {}'.format(('Incorrect action value'),
|
|
||||||
action)})
|
|
||||||
|
|
||||||
id = request.POST.get('id', None)
|
|
||||||
if id is None:
|
|
||||||
return render(request,
|
|
||||||
'error.html',
|
|
||||||
{'error': '{}: {}'.format(('Incorrect id value'), id)})
|
|
||||||
|
|
||||||
conflict = MemberConflict.objects.get(id=id)
|
|
||||||
first_member = conflict.first_member
|
|
||||||
second_member = conflict.second_member
|
|
||||||
|
|
||||||
if action == 'first':
|
|
||||||
for payment in second_member.payments.all():
|
|
||||||
payment.member = first_member
|
|
||||||
payment.save()
|
|
||||||
second_member.delete()
|
|
||||||
elif action == 'second':
|
|
||||||
for payment in first_member.payments.all():
|
|
||||||
payment.member = second_member
|
|
||||||
payment.save()
|
|
||||||
first_member.delete()
|
|
||||||
|
|
||||||
conflict.delete()
|
|
||||||
|
|
||||||
if MemberConflict.objects.exists():
|
|
||||||
return HttpResponseRedirect('/members/duplicates')
|
|
||||||
else:
|
|
||||||
notification = _('Successfully resolved all member conflicts.')
|
|
||||||
return HttpResponseRedirect(
|
|
||||||
'/members/list?notification={}'.format(html.escape(notification)))
|
|
||||||
|
|
||||||
|
|
||||||
def send_mail_wrapper(subject, message, email_to):
|
def send_mail_wrapper(subject, message, email_to):
|
||||||
"""Send mail to default email."""
|
"""Send mail to default email."""
|
||||||
send_mail(subject,
|
send_mail(subject,
|
||||||
@@ -653,27 +643,6 @@ def email_on_accept(sender, instance, created, **kwargs):
|
|||||||
logging.error('Failed to send email to accepted member!')
|
logging.error('Failed to send email to accepted member!')
|
||||||
|
|
||||||
|
|
||||||
def check_for_duplicates(instance):
|
|
||||||
"""Check for member duplicates."""
|
|
||||||
name_candidates = Member.objects.filter(first_name=instance.first_name,
|
|
||||||
last_name=instance.last_name)
|
|
||||||
email_candidates = Member.objects.filter(email=instance.email)
|
|
||||||
|
|
||||||
candidates = name_candidates | email_candidates
|
|
||||||
duplicates = candidates.exclude(id=instance.id)
|
|
||||||
|
|
||||||
if len(duplicates) > 0:
|
|
||||||
conflict = MemberConflict(first_member=instance,
|
|
||||||
second_member=duplicates[0])
|
|
||||||
conflict.save()
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Member)
|
|
||||||
def duplicate_receiver(sender, instance, created, **kwargs):
|
|
||||||
"""Call check_for_duplicates function."""
|
|
||||||
check_for_duplicates(instance)
|
|
||||||
|
|
||||||
|
|
||||||
# Can be used to retrieve single member information via REST API
|
# Can be used to retrieve single member information via REST API
|
||||||
class MemberDetail(generics.RetrieveAPIView):
|
class MemberDetail(generics.RetrieveAPIView):
|
||||||
"""Member detail rest API view."""
|
"""Member detail rest API view."""
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ then
|
|||||||
USE_NPM="false"
|
USE_NPM="false"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$INTERACTIVE || echo "Running in non-interactive mode." && env
|
$INTERACTIVE || (echo "Running in non-interactive mode." && env)
|
||||||
|
|
||||||
$INTERACTIVE && read -p "Are these programs installed? [y/n]" -n 1 -r || REPLY="y"
|
$INTERACTIVE && read -p "Are these programs installed? [y/n]" -n 1 -r || REPLY="y"
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
+1
-1
@@ -8,4 +8,4 @@ class OhlhafvForm(forms.ModelForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OhlhafvChallenge
|
model = OhlhafvChallenge
|
||||||
fields = ['challenger', 'challenger_email', 'victim', 'victim_email', 'series', 'message']
|
fields = ['challenger', 'challenger_email', 'victim', 'victim_email', 'series', 'message']
|
||||||
|
|||||||
+1
-1
@@ -5,4 +5,4 @@ from webapp.models import OhlhafvChallenge
|
|||||||
|
|
||||||
class OhlhafvTable(tables.Table):
|
class OhlhafvTable(tables.Table):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OhlhafvChallenge
|
model = OhlhafvChallenge
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ urlpatterns = [
|
|||||||
# git revision
|
# git revision
|
||||||
url(r'^about', about_view),
|
url(r'^about', about_view),
|
||||||
|
|
||||||
#ohlhafv
|
# ohlhafv
|
||||||
url(r'^ohlhafv$', ohlhafv_view),
|
url(r'^ohlhafv$', ohlhafv_view),
|
||||||
url(r'^ohlhafv/submit', ohlhafv_submit),
|
url(r'^ohlhafv/submit', ohlhafv_submit),
|
||||||
url(r'^ohlhafv/list', ohlhafv_list),
|
url(r'^ohlhafv/list', ohlhafv_list),
|
||||||
|
|||||||
+2
-2
@@ -75,10 +75,10 @@ def ohlhafv_submit(request, *args, **kwargs):
|
|||||||
form = OhlhafvForm(request.POST)
|
form = OhlhafvForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
#return HttpResponseRedirect('/list/')
|
# return HttpResponseRedirect('/list/')
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
#return render(request, 'error.html', {'error': form.errors})
|
# return render(request, 'error.html', {'error': form.errors})
|
||||||
return HttpResponseRedirect('/ohlhafv/list/')
|
return HttpResponseRedirect('/ohlhafv/list/')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user