Verified Commit 4a0a9088 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Add functionality to admin to edit information fields

parent ee539787
...@@ -120,4 +120,12 @@ events.views module ...@@ -120,4 +120,12 @@ events.views module
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
events.widgets module
---------------------
.. automodule:: events.widgets
:members:
:undoc-members:
:show-inheritance:
...@@ -15,6 +15,7 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -15,6 +15,7 @@ from django.utils.translation import ugettext_lazy as _
from activemembers.models import MemberGroup from activemembers.models import MemberGroup
from events import services from events import services
from events.forms import RegistrationAdminForm
from members.models import Member from members.models import Member
from payments.widgets import PaymentWidget from payments.widgets import PaymentWidget
from pizzas.models import PizzaEvent from pizzas.models import PizzaEvent
...@@ -268,6 +269,7 @@ class EventAdmin(DoNextModelAdmin): ...@@ -268,6 +269,7 @@ class EventAdmin(DoNextModelAdmin):
@admin.register(models.Registration) @admin.register(models.Registration)
class RegistrationAdmin(DoNextModelAdmin): class RegistrationAdmin(DoNextModelAdmin):
"""Custom admin for registrations""" """Custom admin for registrations"""
form = RegistrationAdminForm
def save_model(self, request, registration, form, change): def save_model(self, request, registration, form, change):
if not services.is_organiser(request.member, registration.event): if not services.is_organiser(request.member, registration.event):
...@@ -327,3 +329,13 @@ class RegistrationAdmin(DoNextModelAdmin): ...@@ -327,3 +329,13 @@ class RegistrationAdmin(DoNextModelAdmin):
# Filter the queryset to current members only # Filter the queryset to current members only
kwargs['queryset'] = Member.current_members.all() kwargs['queryset'] = Member.current_members.all()
return super().formfield_for_foreignkey(db_field, request, **kwargs) return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('<int:pk>/fields/',
self.admin_site.admin_view(
admin_views.RegistrationAdminFields.as_view(admin=self)),
name='events_registration_fields'),
]
return custom_urls + urls
import csv import csv
from django.contrib import messages
from django.contrib.admin import helpers
from django.contrib.admin.views.decorators import staff_member_required from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
...@@ -11,13 +13,16 @@ from django.utils.text import slugify ...@@ -11,13 +13,16 @@ from django.utils.text import slugify
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views import View from django.views import View
from django.views.generic import DetailView, TemplateView from django.views.generic import DetailView, TemplateView, FormView
from events import services
from events.decorators import organiser_only from events.decorators import organiser_only
from events.exceptions import RegistrationError
from events.forms import FieldsForm
from .models import Event, Registration from .models import Event, Registration
@method_decorator([staff_member_required, ], name='dispatch') @method_decorator(staff_member_required, name='dispatch')
@method_decorator(organiser_only, name='dispatch') @method_decorator(organiser_only, name='dispatch')
class EventAdminDetails(DetailView, PermissionRequiredMixin): class EventAdminDetails(DetailView, PermissionRequiredMixin):
""" """
...@@ -29,7 +34,83 @@ class EventAdminDetails(DetailView, PermissionRequiredMixin): ...@@ -29,7 +34,83 @@ class EventAdminDetails(DetailView, PermissionRequiredMixin):
permission_required = 'events.change_event' permission_required = 'events.change_event'
@method_decorator([staff_member_required, ], name='dispatch') @method_decorator(staff_member_required, name='dispatch')
@method_decorator(organiser_only, name='dispatch')
class RegistrationAdminFields(FormView):
"""
Renders a form that allows the user to change the details of their
registration. The user should be authenticated.
"""
form_class = FieldsForm
template_name = 'admin/change_form.html'
registration = None
admin = None
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
**self.admin.admin_site.each_context(self.request),
'add': False,
'change': True,
'has_view_permission': True,
'has_add_permission': False,
'has_change_permission':
self.request.user.has_perms('events.change_registration'),
'has_delete_permission': False,
'has_editable_inline_admin_formsets': False,
'app_label': 'events',
'opts': self.registration._meta,
'is_popup': False,
'save_as': False,
'save_on_top': False,
'original': self.registration,
'obj_id': self.registration.pk,
'title': _('Change registration fields'),
'adminform': helpers.AdminForm(context['form'], (
(None, {
'fields': [f for f in context['form'].fields.keys()]
}),
), {})
})
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["fields"] = services.registration_fields(
self.request, registration=self.registration)
return kwargs
def form_valid(self, form):
values = form.field_values()
try:
services.update_registration(registration=self.registration,
field_values=values)
messages.success(self.request,
_("Registration successfully saved."))
if '_save' in self.request.POST:
return HttpResponseRedirect(reverse(
'admin:events_registration_change',
args=[str(self.registration.pk)]
))
except RegistrationError as e:
messages.error(self.request, e)
return self.render_to_response(self.get_context_data(form=form))
def dispatch(self, request, *args, **kwargs):
self.registration = get_object_or_404(
Registration, pk=self.kwargs['pk'])
try:
if self.registration.event.has_fields():
return super().dispatch(request, *args, **kwargs)
except RegistrationError:
pass
return HttpResponseRedirect(reverse(
'admin:events_registration_change',
args=[str(self.registration.pk)]
))
@method_decorator(staff_member_required, name='dispatch')
@method_decorator(organiser_only, name='dispatch') @method_decorator(organiser_only, name='dispatch')
class EventRegistrationsExport(View, PermissionRequiredMixin): class EventRegistrationsExport(View, PermissionRequiredMixin):
""" """
...@@ -125,7 +206,7 @@ class EventRegistrationsExport(View, PermissionRequiredMixin): ...@@ -125,7 +206,7 @@ class EventRegistrationsExport(View, PermissionRequiredMixin):
return response return response
@method_decorator([staff_member_required, ], name='dispatch') @method_decorator(staff_member_required, name='dispatch')
@method_decorator(organiser_only, name='dispatch') @method_decorator(organiser_only, name='dispatch')
class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin): class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin):
""" """
...@@ -149,7 +230,7 @@ class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin): ...@@ -149,7 +230,7 @@ class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin):
return context return context
@method_decorator([staff_member_required, ], name='dispatch') @method_decorator(staff_member_required, name='dispatch')
@method_decorator(organiser_only, name='dispatch') @method_decorator(organiser_only, name='dispatch')
class EventRegistrationsMarkPresent(View, PermissionRequiredMixin): class EventRegistrationsMarkPresent(View, PermissionRequiredMixin):
""" """
......
from django import forms from django import forms
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .models import RegistrationInformationField, Event from .models import RegistrationInformationField, Event, Registration
from .widgets import FieldsWidget
class RegistrationAdminForm(forms.ModelForm):
"""
Custom admin form to add a link to the registration information
fields admin
"""
fields = forms.URLField(widget=FieldsWidget)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance.event.has_fields():
self.fields['fields'].initial = (
reverse('admin:events_registration_fields',
args=[self.instance.pk]))
else:
self.fields['fields'].widget = self.fields[
'fields'].hidden_widget()
class Meta:
fields = '__all__'
model = Registration
class RegistrationInformationFieldForm(forms.ModelForm): class RegistrationInformationFieldForm(forms.ModelForm):
......
{% load i18n %}
<div class="readonly">
<a href="{{ widget.value }}" class="button">{% trans "Edit information fields" %}</a>
</div>
"""Widgets provided by the payments package"""
from django.forms import Widget
class FieldsWidget(Widget):
"""
Custom widget for linking to the fields, used in registrations
"""
template_name = 'events/admin/fields_widget.html'
def value_from_datadict(self, data, files, name):
return super().value_from_datadict(data, files, name)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment