manage announcements

This commit is contained in:
Laura Klünder 2017-12-10 15:23:53 +01:00
parent fe3bac40c8
commit 56a672cef6
8 changed files with 150 additions and 4 deletions

View file

@ -8,7 +8,9 @@ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy from django.utils.translation import ungettext_lazy
from c3nav.control.models import UserPermissions from c3nav.control.models import UserPermissions
from c3nav.mapdata.forms import I18nModelFormMixin
from c3nav.mapdata.models.access import AccessPermissionToken, AccessPermissionTokenItem, AccessRestriction from c3nav.mapdata.models.access import AccessPermissionToken, AccessPermissionTokenItem, AccessRestriction
from c3nav.site.models import Announcement
class UserPermissionsForm(ModelForm): class UserPermissionsForm(ModelForm):
@ -108,3 +110,13 @@ class AccessPermissionForm(Form):
return AccessPermissionToken(author=self.author, return AccessPermissionToken(author=self.author,
can_grant=self.cleaned_data.get('can_grant', '0') == '1', can_grant=self.cleaned_data.get('can_grant', '0') == '1',
restrictions=tuple(restrictions)) restrictions=tuple(restrictions))
class AnnouncementForm(I18nModelFormMixin, ModelForm):
class Meta:
model = Announcement
fields = ('text', 'active', 'active_until')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['active_until'].initial = timezone.now()

View file

@ -0,0 +1,12 @@
{% extends 'control/base.html' %}
{% load i18n %}
{% block heading %}{% trans 'Edit announcement' %}{% endblock %}
{% block subcontent %}
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">{% trans 'Save' %}</button>
</form>
{% endblock %}

View file

@ -0,0 +1,34 @@
{% extends 'control/base.html' %}
{% load i18n %}
{% block heading %}{% trans 'Users' %}{% endblock %}
{% block subcontent %}
<table>
<tr>
<th>{% trans 'ID' %}</th>
<th>{% trans 'Text' %}</th>
<th>{% trans 'Author' %}</th>
<th>{% trans 'Active' %}</th>
<th>{% trans 'Active until' %}</th>
<th></th>
</tr>
{% for announcement in announcements %}
<tr>
<td>{{ announcement.id }}</td>
<td>{{ announcement.text }}</td>
<td>{{ announcement.author }}</td>
<td>{{ announcement.active }}</td>
<td>{{ announcement.active_until }}</td>
<td><a href="{% url 'control.announcements.detail' announcement=user.pk %}">{% trans 'Edit' %}</a></td>
</tr>
{% endfor %}
</table>
<h4>{% trans 'Create new announcement' %}</h4>
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">{% trans 'Create new announcement' %}</button>
</form>
{% endblock %}

View file

@ -15,6 +15,9 @@
<a href="{% url 'control.index' %}">{% trans 'Overview' %}</a> &middot; <a href="{% url 'control.index' %}">{% trans 'Overview' %}</a> &middot;
<a href="{% url 'control.users' %}">{% trans 'Users' %}</a> &middot; <a href="{% url 'control.users' %}">{% trans 'Users' %}</a> &middot;
<a href="{% url 'control.access' %}">{% trans 'Access' %}</a> <a href="{% url 'control.access' %}">{% trans 'Access' %}</a>
{% if request.user_permissions.manage_announcements %}
&middot; <a href="{% url 'control.announcements' %}">{% trans 'Announcements' %}</a>
{% endif %}
</p> </p>
</nav> </nav>
{% endblock %} {% endblock %}

View file

@ -1,11 +1,14 @@
from django.conf.urls import url from django.conf.urls import url
from c3nav.control.views import grant_access, grant_access_qr, main_index, user_detail, user_list from c3nav.control.views import (announcement_detail, announcement_list, grant_access, grant_access_qr, main_index,
user_detail, user_list)
urlpatterns = [ urlpatterns = [
url(r'^users/$', user_list, name='control.users'), url(r'^users/$', user_list, name='control.users'),
url(r'^users/(?P<user>\d+)/$', user_detail, name='control.users.detail'), url(r'^users/(?P<user>\d+)/$', user_detail, name='control.users.detail'),
url(r'^access/$', grant_access, name='control.access'), url(r'^access/$', grant_access, name='control.access'),
url(r'^access/(?P<token>[^/]+)$', grant_access_qr, name='control.access.qr'), url(r'^access/(?P<token>[^/]+)$', grant_access_qr, name='control.access.qr'),
url(r'^announcements/$', announcement_list, name='control.announcements'),
url(r'^announcements/(?P<announcement>\d+)/$', announcement_detail, name='control.announcements.detail'),
url(r'^$', main_index, name='control.index'), url(r'^$', main_index, name='control.index'),
] ]

View file

@ -11,9 +11,10 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from c3nav.control.forms import AccessPermissionForm, UserPermissionsForm from c3nav.control.forms import AccessPermissionForm, AnnouncementForm, UserPermissionsForm
from c3nav.control.models import UserPermissions from c3nav.control.models import UserPermissions
from c3nav.mapdata.models.access import AccessPermission, AccessPermissionToken from c3nav.mapdata.models.access import AccessPermission, AccessPermissionToken
from c3nav.site.models import Announcement
def control_panel_view(func): def control_panel_view(func):
@ -170,3 +171,49 @@ def grant_access_qr(request, token):
'url_qr': reverse('site.qr', kwargs={'path': url}), 'url_qr': reverse('site.qr', kwargs={'path': url}),
'url_absolute': request.build_absolute_uri(url), 'url_absolute': request.build_absolute_uri(url),
}) })
@login_required
@control_panel_view
def announcement_list(request):
if not request.user_permissions.manage_announcements:
raise PermissionDenied
announcements = Announcement.objects.order_by('id')
if request.method == 'POST':
form = AnnouncementForm(data=request.POST)
if form.is_valid():
announcement = form.instance
announcement = request.user
announcement.save()
return redirect('control.announcements')
else:
form = AnnouncementForm()
return render(request, 'control/announcements.html', {
'form': form,
'announcements': announcements,
})
@login_required
@control_panel_view
def announcement_detail(request, announcement):
if not request.user_permissions.manage_announcements:
raise PermissionDenied
announcement = get_object_or_404(Announcement, pk=announcement)
if request.method == 'POST':
form = AnnouncementForm(instance=announcement, data=request.POST)
if form.is_valid():
form.save()
return redirect('control.announcements')
else:
form = AnnouncementForm(instance=announcement)
return render(request, 'control/announcement.html', {
'form': form,
'announcement': announcement,
})

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-10 14:14
from __future__ import unicode_literals
import c3nav.mapdata.fields
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('site', '0001_announcement'),
]
operations = [
migrations.RemoveField(
model_name='announcement',
name='message',
),
migrations.AddField(
model_name='announcement',
name='author',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='announcements', to=settings.AUTH_USER_MODEL, verbose_name='author'),
),
migrations.AddField(
model_name='announcement',
name='text',
field=c3nav.mapdata.fields.I18nField(fallback_any=True, verbose_name='Text'),
),
]

View file

@ -1,3 +1,4 @@
from django.conf import settings
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.utils import timezone from django.utils import timezone
@ -10,7 +11,8 @@ class Announcement(models.Model):
created = models.DateTimeField(auto_now_add=True, verbose_name=_('created')) created = models.DateTimeField(auto_now_add=True, verbose_name=_('created'))
active_until = models.DateTimeField(null=True, verbose_name=_('active until')) active_until = models.DateTimeField(null=True, verbose_name=_('active until'))
active = models.BooleanField(default=True, verbose_name=_('active')) active = models.BooleanField(default=True, verbose_name=_('active'))
message = I18nField(_('Message')) author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author'))
text = I18nField(_('Text'), fallback_any=True)
class Meta: class Meta:
verbose_name = _('Announcement') verbose_name = _('Announcement')
@ -22,6 +24,6 @@ class Announcement(models.Model):
def get_current(cls): def get_current(cls):
try: try:
return cls.objects.filter(Q(active=True) & (Q(active_until__isnull=True) | return cls.objects.filter(Q(active=True) & (Q(active_until__isnull=True) |
Q(active_until__isnull=timezone.now()))).latest() Q(active_until__gt=timezone.now()))).latest()
except cls.DoesNotExist: except cls.DoesNotExist:
return None return None