mirror of
https://github.com/pretix/pretix.git
synced 2026-08-24 13:02:00 +00:00
Add a view for GlobalSettings
This commit is contained in:
committed by
Raphael Michel
parent
02fd0a8e06
commit
c647aa9f4e
@@ -305,7 +305,7 @@ Your {event} team"""))
|
|||||||
|
|
||||||
class SettingsProxy:
|
class SettingsProxy:
|
||||||
"""
|
"""
|
||||||
This objects allows convenient access to settings stored in the
|
This object allows convenient access to settings stored in the
|
||||||
EventSettings/OrganizerSettings database model. It exposes all settings as
|
EventSettings/OrganizerSettings database model. It exposes all settings as
|
||||||
properties and it will do all the nasty inheritance and defaults stuff for
|
properties and it will do all the nasty inheritance and defaults stuff for
|
||||||
you.
|
you.
|
||||||
@@ -442,7 +442,7 @@ class SettingsProxy:
|
|||||||
|
|
||||||
def set(self, key: str, value: Any) -> None:
|
def set(self, key: str, value: Any) -> None:
|
||||||
"""
|
"""
|
||||||
Stores a setting to the database of this object.
|
Stores a setting to the database of its object.
|
||||||
"""
|
"""
|
||||||
if key in self._cache():
|
if key in self._cache():
|
||||||
s = self._cache()[key]
|
s = self._cache()[key]
|
||||||
|
|||||||
@@ -122,3 +122,9 @@ be everything between a minute and a day. The actions you perform should be
|
|||||||
idempotent, i.e. it should not make a difference if this is sent out more often
|
idempotent, i.e. it should not make a difference if this is sent out more often
|
||||||
than expected.
|
than expected.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
register_global_settings = django.dispatch.Signal()
|
||||||
|
"""
|
||||||
|
All plugins that are installed may send fields for the global settings form, as
|
||||||
|
an OrderedDict of (setting name, form field).
|
||||||
|
"""
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from pretix.base.forms import SettingsForm
|
||||||
|
from pretix.base.i18n import I18nFormField, I18nTextInput
|
||||||
|
from pretix.base.models.settings import GlobalSetting
|
||||||
|
from pretix.base.settings import SettingsProxy
|
||||||
|
from pretix.base.signals import register_global_settings
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalSettingsObject:
|
||||||
|
def __init__(self):
|
||||||
|
self.settings = SettingsProxy(self, type=GlobalSetting)
|
||||||
|
self.setting_objects = GlobalSetting.objects
|
||||||
|
self.slug = 'GLOBALSETTINGS'
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalSettingsForm(SettingsForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.obj = GlobalSettingsObject()
|
||||||
|
super().__init__(*args, obj=self.obj, **kwargs)
|
||||||
|
|
||||||
|
self.fields = OrderedDict([
|
||||||
|
('footer_text', I18nFormField(
|
||||||
|
widget=I18nTextInput,
|
||||||
|
required=False,
|
||||||
|
label=_("Additional footer text"),
|
||||||
|
help_text=_("Will be included as additional text in the footer, site-wide.")
|
||||||
|
)),
|
||||||
|
('footer_link', I18nFormField(
|
||||||
|
widget=I18nTextInput,
|
||||||
|
required=False,
|
||||||
|
label=_("Additional footer link"),
|
||||||
|
help_text=_("Will be included as the link in the additional footer text.")
|
||||||
|
))
|
||||||
|
])
|
||||||
|
responses = register_global_settings.send(self)
|
||||||
|
for r, response in responses:
|
||||||
|
for key, value in response.items():
|
||||||
|
# We need to be this explicit, since OrderedDict.update does not retain ordering
|
||||||
|
self.fields[key] = value
|
||||||
@@ -81,7 +81,7 @@ def organizer_permission_required(permission):
|
|||||||
|
|
||||||
class OrganizerPermissionRequiredMixin:
|
class OrganizerPermissionRequiredMixin:
|
||||||
"""
|
"""
|
||||||
This mixin is equivalent to the event_permission_required view decorator but
|
This mixin is equivalent to the organizer_permission_required view decorator but
|
||||||
is in a form suitable for class-based views.
|
is in a form suitable for class-based views.
|
||||||
"""
|
"""
|
||||||
permission = ''
|
permission = ''
|
||||||
@@ -90,3 +90,33 @@ class OrganizerPermissionRequiredMixin:
|
|||||||
def as_view(cls, **initkwargs):
|
def as_view(cls, **initkwargs):
|
||||||
view = super(OrganizerPermissionRequiredMixin, cls).as_view(**initkwargs)
|
view = super(OrganizerPermissionRequiredMixin, cls).as_view(**initkwargs)
|
||||||
return organizer_permission_required(cls.permission)(view)
|
return organizer_permission_required(cls.permission)(view)
|
||||||
|
|
||||||
|
|
||||||
|
def administrator_permission_required(permission):
|
||||||
|
"""
|
||||||
|
This view decorator rejects all requests with a 403 response which are not from
|
||||||
|
users with the is_superuser flag.
|
||||||
|
"""
|
||||||
|
def decorator(function):
|
||||||
|
def wrapper(request, *args, **kw):
|
||||||
|
if not request.user.is_authenticated: # NOQA
|
||||||
|
# just a double check, should not ever happen
|
||||||
|
raise PermissionDenied()
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
raise PermissionDenied(_('You do not have permission to view this content.'))
|
||||||
|
return function(request, *args, **kw)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
class AdministratorPermissionRequiredMixin:
|
||||||
|
"""
|
||||||
|
This mixin is equivalent to the administrator_permission_required view decorator but
|
||||||
|
is in a form suitable for class-based views.
|
||||||
|
"""
|
||||||
|
permission = ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_view(cls, **initkwargs):
|
||||||
|
view = super(AdministratorPermissionRequiredMixin, cls).as_view(**initkwargs)
|
||||||
|
return administrator_permission_required(cls.permission)(view)
|
||||||
|
|||||||
@@ -101,6 +101,14 @@
|
|||||||
{% trans "Dashboard" %}
|
{% trans "Dashboard" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'control:global-settings' %}" {% if "global-settings" in url_name %}class="active"{% endif %}>
|
||||||
|
<i class="fa fa-wrench fa-fw"></i>
|
||||||
|
{% trans "Global settings" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'control:events' %}" {% if "events" in url_name %}class="active"{% endif %}>
|
<a href="{% url 'control:events' %}" {% if "events" in url_name %}class="active"{% endif %}>
|
||||||
<i class="fa fa-calendar fa-fw"></i>
|
<i class="fa fa-calendar fa-fw"></i>
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{% extends "pretixcontrol/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Global settings" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans "Global settings" %}</h1>
|
||||||
|
<form action="" method="post" class="form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form_errors form %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
<div class="form-group submit-group">
|
||||||
|
<button type="submit" class="btn btn-primary btn-save">
|
||||||
|
{% trans "Save" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
|
|
||||||
from pretix.control.views import (
|
from pretix.control.views import (
|
||||||
auth, dashboards, event, help, item, main, orders, organizer, user,
|
auth, dashboards, event, global_settings, help, item, main, orders,
|
||||||
vouchers,
|
organizer, user, vouchers,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -13,6 +13,7 @@ urlpatterns = [
|
|||||||
url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
||||||
url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
||||||
url(r'^$', dashboards.user_index, name='index'),
|
url(r'^$', dashboards.user_index, name='index'),
|
||||||
|
url(r'^settings/$', global_settings.GlobalSettingsView.as_view(), name='global-settings'),
|
||||||
url(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
url(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
||||||
url(r'^settings$', user.UserSettings.as_view(), name='user.settings'),
|
url(r'^settings$', user.UserSettings.as_view(), name='user.settings'),
|
||||||
url(r'^settings/2fa/$', user.User2FAMainView.as_view(), name='user.settings.2fa'),
|
url(r'^settings/2fa/$', user.User2FAMainView.as_view(), name='user.settings.2fa'),
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
from django.views.generic import FormView
|
||||||
|
|
||||||
|
from pretix.control.forms.global_settings import GlobalSettingsForm
|
||||||
|
from pretix.control.permissions import AdministratorPermissionRequiredMixin
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalSettingsView(AdministratorPermissionRequiredMixin, FormView):
|
||||||
|
template_name = 'pretixcontrol/global_settings.html'
|
||||||
|
form_class = GlobalSettingsForm
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.save()
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
from django.shortcuts import reverse
|
||||||
|
return reverse('control:global-settings')
|
||||||
Reference in New Issue
Block a user