Commit 1ca6bf7c authored by Skia's avatar Skia
Browse files

Add news system, still miss nices templates and moderation tools

parent f79ffbee
Pipeline #605 passed with stage
in 2 minutes and 28 seconds
......@@ -3,6 +3,7 @@ from django.contrib import admin
from com.models import *
admin.site.register(Sith)
admin.site.register(News)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('club', '0005_auto_20161120_1149'),
('com', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='News',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
('title', models.CharField(max_length=64, verbose_name='title')),
('summary', models.TextField(verbose_name='summary')),
('content', models.TextField(verbose_name='content')),
('type', models.CharField(max_length=16, choices=[('NOTICE', 'Notice'), ('EVENT', 'Event'), ('WEEKLY', 'Weekly'), ('CALL', 'Call')], default='EVENT', verbose_name='type')),
('is_moderated', models.BooleanField(default=False, verbose_name='is moderated')),
('club', models.ForeignKey(to='club.Club', verbose_name='club', related_name='news')),
('moderator', models.ForeignKey(verbose_name='owner', to=settings.AUTH_USER_MODEL, related_name='moderated_news', null=True)),
('owner', models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='owner', related_name='owned_news')),
],
),
migrations.CreateModel(
name='NewsDate',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
('start_date', models.DateTimeField(null=True, blank=True, verbose_name='start_date')),
('end_date', models.DateTimeField(null=True, blank=True, verbose_name='end_date')),
('news', models.ForeignKey(to='com.News', verbose_name='news_date', related_name='dates')),
],
),
]
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse_lazy, reverse
from django.conf import settings
from core.models import User
from club.models import Club
class Sith(models.Model):
"""A one instance class storing all the modifiable infos"""
alert_msg = models.TextField(_("alert message"), default="", blank=True)
info_msg = models.TextField(_("info message"), default="", blank=True)
index_page = models.TextField(_("index page"), default="", blank=True)
......@@ -13,3 +18,40 @@ class Sith(models.Model):
def __str__(self):
return "⛩ Sith ⛩"
NEWS_TYPES = [
('NOTICE', _('Notice')),
('EVENT', _('Event')),
('WEEKLY', _('Weekly')),
('CALL', _('Call')),
]
class News(models.Model):
"""The news class"""
title = models.CharField(_("title"), max_length=64)
summary = models.TextField(_("summary"))
content = models.TextField(_("content"))
type = models.CharField(_("type"), max_length=16, choices=NEWS_TYPES, default="EVENT")
club = models.ForeignKey(Club, related_name="news", verbose_name=_("club"))
owner = models.ForeignKey(User, related_name="owned_news", verbose_name=_("owner"))
is_moderated = models.BooleanField(_("is moderated"), default=False)
moderator = models.ForeignKey(User, related_name="moderated_news", verbose_name=_("owner"), null=True)
def get_absolute_url(self):
return reverse('com:news_detail', kwargs={'news_id': self.id})
def __str__(self):
return "%s: %s" % (self.type, self.title)
class NewsDate(models.Model):
"""
A date class, useful for weekly events, or for events that just have no date
This class allows more flexibilty managing the dates related to a news, particularly when this news is weekly, since
we don't have to make copies
"""
news = models.ForeignKey(News, related_name="dates", verbose_name=_("news_date"))
start_date = models.DateTimeField(_('start_date'), null=True, blank=True)
end_date = models.DateTimeField(_('end_date'), null=True, blank=True)
def __str__(self):
return "%s: %s - %s" % (self.news.title, self.start_date, self.end_date)
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}News admin{% endtrans %}
{% endblock %}
{% block content %}
<h3>{% trans %}News{% endtrans %}</h3>
<ul>
{% for news in object_list %}
<li>
<p>{{ news.get_type_display() }} - {{ news.title }}:
<span>{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span> -
<a href="{{ url('com:news_edit', news_id=news.id) }}">{% trans %}Edit{% endtrans %}</a>
</p>
</li>
{% endfor %}
</ul>
{% endblock %}
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}News{% endtrans %} -
{{ object.title }}
{% endblock %}
{% block content %}
<h3>{% trans %}News{% endtrans %}</h3>
{{ object }}
{{ object.dates.all() }}
{% endblock %}
{% extends "core/base.jinja" %}
{% block title %}
{% if object %}
{% trans %}Edit news{% endtrans %}
{% else %}
{% trans %}Create news{% endtrans %}
{% endif %}
{% endblock %}
{% block content %}
{% if object %}
<h2>{% trans %}Edit news{% endtrans %}</h2>
{% else %}
<h2>{% trans %}Create news{% endtrans %}</h2>
{% endif %}
<form action="" method="post">
{% csrf_token %}
{{ form.non_field_errors() }}
{{ form.owner }}
<p>{{ form.type.errors }}<label for="{{ form.type.name }}">{{ form.type.label }}</label> {{ form.type }}</p>
<p class="date">{{ form.start_date.errors }}<label for="{{ form.start_date.name }}">{{ form.start_date.label }}</label> {{ form.start_date }}</p>
<p class="date">{{ form.end_date.errors }}<label for="{{ form.end_date.name }}">{{ form.end_date.label }}</label> {{ form.end_date }}</p>
<p class="until">{{ form.until.errors }}<label for="{{ form.until.name }}">{{ form.until.label }}</label> {{ form.until }}</p>
<p>{{ form.title.errors }}<label for="{{ form.title.name }}">{{ form.title.label }}</label> {{ form.title }}</p>
<p>{{ form.club.errors }}<label for="{{ form.club.name }}">{{ form.club.label }}</label> {{ form.club }}</p>
<p>{{ form.summary.errors }}<label for="{{ form.summary.name }}">{{ form.summary.label }}</label> {{ form.summary }}</p>
<p>{{ form.content.errors }}<label for="{{ form.content.name }}">{{ form.content.label }}</label> {{ form.content }}</p>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>
{% endblock %}
{% block script %}
{{ super() }}
<script>
$( function() {
var type = $('input[name=type]');
var dates = $('.date');
var until = $('.until');
function update_targets () {
type_checked = $('input[name=type]:checked');
if (type_checked.val() == "EVENT" || type_checked.val() == "CALL") {
dates.show();
until.hide();
} else if (type_checked.val() == "WEEKLY") {
dates.show();
until.show();
} else {
dates.hide();
until.hide();
}
}
update_targets();
type.change(update_targets);
} );
</script>
{% endblock %}
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}News{% endtrans %}
{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css" media="all">
section {
padding: 5px;
}
section.news_call {
background: lightgrey;
}
section.news_event:nth-child(even) {
background: lightblue;
}
.date {
font-size: small;
color: grey;
}
</style>
{% endblock %}
{% block content %}
<h3>{% trans %}News{% endtrans %}</h3>
<hr>
<h4>Notice</h4>
{% for news in object_list.filter(type="NOTICE") %}
<section class="news_notice">
<h4>{{ news.title }}</h4>
<p>{{ news.summary }}</p>
</section>
{% endfor %}
<hr>
<h4>Calls</h4>
{% for news in object_list.filter(dates__start_date__lte=timezone.now(), dates__end_date__gte=timezone.now(), type="CALL") %}
<section class="news_call">
<h4>{{ news.title }}</h4>
<p class="date">
<span>{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
</p>
<p>{{ news.summary }}</p>
</section>
{% endfor %}
<hr>
<h4>Events</h4>
{% for news in object_list.filter(dates__end_date__gte=timezone.now(), type="EVENT") %}
<section class="news_event">
<h4>{{ news.title }}</h4>
<p class="date">
<span>{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
</p>
<p><a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a></p>
<p>{{ news.summary|markdown }}</p>
</section>
{% endfor %}
<hr>
<h4>Weekly</h4>
{% for news in object_list.filter(dates__end_date__gte=timezone.now(), type="WEEKLY").distinct() %}
<!-- buggy when more than one news, anyway, we won't use it this way -->
{% for d in news.dates.all() %}
<section class="news_weekly">
<h4>{{ news.title }}</h4>
<p class="date">
<span>{{ d.start_date|localtime|date(DATETIME_FORMAT) }}
{{ d.start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ d.end_date|localtime|date(DATETIME_FORMAT) }}
{{ d.end_date|localtime|time(DATETIME_FORMAT) }}</span>
</p>
<p><a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a></p>
<p>{{ news.summary|markdown }}</p>
</section>
{% endfor %}
{% endfor %}
{% endblock %}
......@@ -3,8 +3,13 @@ from django.conf.urls import url, include
from com.views import *
urlpatterns = [
url(r'^edit/alert$', AlertMsgEditView.as_view(), name='alert_edit'),
url(r'^edit/info$', InfoMsgEditView.as_view(), name='info_edit'),
url(r'^edit/index$', IndexEditView.as_view(), name='index_edit'),
url(r'^sith/edit/alert$', AlertMsgEditView.as_view(), name='alert_edit'),
url(r'^sith/edit/info$', InfoMsgEditView.as_view(), name='info_edit'),
url(r'^sith/edit/index$', IndexEditView.as_view(), name='index_edit'),
url(r'^news$', NewsListView.as_view(), name='news_list'),
url(r'^news/admin$', NewsAdminListView.as_view(), name='news_admin_list'),
url(r'^news/create$', NewsCreateView.as_view(), name='news_new'),
url(r'^news/(?P<news_id>[0-9]+)/edit$', NewsEditView.as_view(), name='news_edit'),
url(r'^news/(?P<news_id>[0-9]+)$', NewsDetailView.as_view(), name='news_detail'),
]
from django.shortcuts import render
from django.views.generic.edit import UpdateView
from django.views.generic import ListView, DetailView, RedirectView
from django.views.generic.edit import UpdateView, CreateView
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse, reverse_lazy
from django.core.exceptions import ValidationError
from django.utils import timezone
from django import forms
from com.models import Sith
from datetime import timedelta
from com.models import Sith, News, NewsDate
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin
from core.views.forms import SelectDateTime
from club.models import Club
# Sith object
sith = Sith.objects.first
......@@ -53,3 +63,87 @@ class IndexEditView(ComEditView):
fields = ['index_page']
current_tab = "index"
success_url = reverse_lazy('com:index_edit')
# News
class NewsForm(forms.ModelForm):
class Meta:
model = News
fields = ['type', 'title', 'club', 'summary', 'content', 'owner']
widgets = {
'owner': forms.HiddenInput,
'type': forms.RadioSelect,
}
start_date = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("Start date"), widget=SelectDateTime, required=False)
end_date = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("End date"), widget=SelectDateTime, required=False)
until = forms.DateTimeField(['%Y-%m-%d %H:%M:%S'], label=_("Until"), widget=SelectDateTime, required=False)
def clean(self):
self.cleaned_data = super(NewsForm, self).clean()
if self.cleaned_data['type'] != "NOTICE":
if not self.cleaned_data['start_date']:
self.add_error('start_date', ValidationError(_("This field is required.")))
if not self.cleaned_data['end_date']:
self.add_error('end_date', ValidationError(_("This field is required.")))
if self.cleaned_data['type'] == "WEEKLY" and not self.cleaned_data['until']:
self.add_error('until', ValidationError(_("This field is required.")))
return self.cleaned_data
def save(self):
ret = super(NewsForm, self).save()
self.instance.dates.all().delete()
if self.instance.type == "EVENT" or self.instance.type == "CALL":
NewsDate(start_date=self.cleaned_data['start_date'],
end_date=self.cleaned_data['end_date'],
news=self.instance).save()
elif self.instance.type == "WEEKLY":
start_date = self.cleaned_data['start_date']
end_date = self.cleaned_data['end_date']
while start_date <= self.cleaned_data['until']:
NewsDate(start_date=start_date,
end_date=end_date,
news=self.instance).save()
start_date += timedelta(days=7)
end_date += timedelta(days=7)
return ret
class NewsEditView(UpdateView):
model = News
form_class = NewsForm
template_name = 'com/news_edit.jinja'
pk_url_kwarg = 'news_id'
def get_initial(self):
init = {}
try:
init['start_date'] = self.object.dates.order_by('id').first().start_date.strftime('%Y-%m-%d %H:%M:%S')
except: pass
try:
init['end_date'] = self.object.dates.order_by('id').first().end_date.strftime('%Y-%m-%d %H:%M:%S')
except: pass
return init
class NewsCreateView(CreateView):
model = News
form_class = NewsForm
template_name = 'com/news_edit.jinja'
def get_initial(self):
init = {'owner': self.request.user}
try:
init['club'] = Club.objects.filter(id=self.request.GET['club']).first()
except: pass
return init
class NewsAdminListView(ListView):
model = News
template_name = 'com/news_admin_list.jinja'
class NewsListView(ListView):
model = News
template_name = 'com/news_list.jinja'
class NewsDetailView(DetailView):
model = News
template_name = 'com/news_detail.jinja'
pk_url_kwarg = 'news_id'
Markdown is supported
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