Merge branch 'master' of https://git.fet.at/bofh/fet2020
This commit is contained in:
@@ -3,7 +3,12 @@ server {
|
|||||||
|
|
||||||
location /assets {
|
location /assets {
|
||||||
alias /app/assets;
|
alias /app/assets;
|
||||||
try_files $uri $uri/ =404;
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /files {
|
||||||
|
alias /app/files;
|
||||||
|
try_files $uri =404;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /fotos {
|
location /fotos {
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .forms import JobPostingForm
|
||||||
from .models import JobPosting
|
from .models import JobPosting
|
||||||
|
|
||||||
|
|
||||||
class JobPostingAdmin(admin.ModelAdmin):
|
class JobPostingAdmin(admin.ModelAdmin):
|
||||||
|
form = JobPostingForm
|
||||||
model = JobPosting
|
model = JobPosting
|
||||||
fieldsets = (
|
|
||||||
(None, {
|
list_display = ['companyName', 'jobName', 'salary', 'publishDate']
|
||||||
'fields': (
|
|
||||||
'companyName',
|
|
||||||
'jobName',
|
|
||||||
'salary',
|
|
||||||
'pdfLocation',
|
|
||||||
'publishDate',
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(JobPosting, JobPostingAdmin)
|
admin.site.register(JobPosting, JobPostingAdmin)
|
||||||
|
|||||||
25
fet2020/blackboard/forms.py
Normal file
25
fet2020/blackboard/forms.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from django import forms
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .models import JobPosting
|
||||||
|
|
||||||
|
|
||||||
|
class JobPostingForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = JobPosting
|
||||||
|
fields = ['companyName', 'jobName', 'salary', 'pdfLocation', 'publishDate']
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
'companyName': _("Firmenname"),
|
||||||
|
'jobName': _("Berufsbezeichnung"),
|
||||||
|
'salary': _("Gehalt"),
|
||||||
|
'pdfLocation': _("Stellenausschreibung"),
|
||||||
|
'publishDate': _("Veröffentlichung"),
|
||||||
|
}
|
||||||
|
|
||||||
|
help_texts = {
|
||||||
|
'pdfLocation': _(
|
||||||
|
"Verwendbare Formate: PDF"
|
||||||
|
),
|
||||||
|
'salary': _("in Euro angeben"),
|
||||||
|
}
|
||||||
@@ -15,12 +15,12 @@ logger = logging.getLogger('blackboard')
|
|||||||
|
|
||||||
|
|
||||||
class JobPosting(models.Model):
|
class JobPosting(models.Model):
|
||||||
companyName = models.CharField(max_length=128)
|
companyName = models.CharField(verbose_name="Firmenname", max_length=128)
|
||||||
jobName = models.CharField(max_length=128)
|
jobName = models.CharField(verbose_name="Berufsbezeichnung", max_length=128)
|
||||||
salary = models.PositiveSmallIntegerField()
|
salary = models.PositiveSmallIntegerField(verbose_name="Gehalt", )
|
||||||
pdfLocation = models.FileField(upload_to='uploads/blackboard/pdf/')
|
pdfLocation = models.FileField(verbose_name="Stellenausschreibung", upload_to='uploads/blackboard/pdf/')
|
||||||
pdf_thumb_location = models.CharField(max_length=128)
|
pdf_thumb_location = models.CharField(max_length=128)
|
||||||
publishDate = models.DateField('date published', default=timezone.now)
|
publishDate = models.DateField(verbose_name="Veröffentlichung", default=timezone.now)
|
||||||
|
|
||||||
# Managers
|
# Managers
|
||||||
all_jobPosting = models.Manager()
|
all_jobPosting = models.Manager()
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ THUMBNAIL_ALIASES = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ETHERPAD CLIENT
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
ETHERPAD_CLIENT = {
|
ETHERPAD_CLIENT = {
|
||||||
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
||||||
@@ -241,20 +241,7 @@ else:
|
|||||||
'apikey': "/app/etherpad/APIKEY.txt"
|
'apikey': "/app/etherpad/APIKEY.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
# REST FRAMEWORK
|
||||||
'DEFAULT_PERMISSION_CLASSES': [
|
|
||||||
'rest_framework.permissions.AllowAny',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# DJANGO MAIL
|
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
|
||||||
EMAIL_HOST = 'buran.htu.tuwien.ac.at'
|
|
||||||
EMAIL_PORT = 587
|
|
||||||
EMAIL_USE_TLS = True
|
|
||||||
|
|
||||||
REST_FRAMEWORK={
|
REST_FRAMEWORK={
|
||||||
'DEFAULT_PERMISSION_CLASSES_CLASSES':[
|
'DEFAULT_PERMISSION_CLASSES_CLASSES':[
|
||||||
'rest_framework.permissions.AllowAny',
|
'rest_framework.permissions.AllowAny',
|
||||||
@@ -262,6 +249,12 @@ REST_FRAMEWORK={
|
|||||||
'DEFAULT_AUTHENTICATION_CLASSES':()
|
'DEFAULT_AUTHENTICATION_CLASSES':()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# DJANGO MAIL
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
|
EMAIL_HOST = 'buran.htu.tuwien.ac.at'
|
||||||
|
EMAIL_PORT = 587
|
||||||
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
# CRON JOBS
|
# CRON JOBS
|
||||||
CRONJOBS = [
|
CRONJOBS = [
|
||||||
('0 16 * * *', 'posts.cronjobs.check_to_send_agenda_mail'),
|
('0 16 * * *', 'posts.cronjobs.check_to_send_agenda_mail'),
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from ckeditor_uploader.widgets import CKEditorUploadingWidget
|
from ckeditor_uploader.widgets import CKEditorUploadingWidget
|
||||||
|
|
||||||
from .models import Member, Job, JobGroup
|
from .models import Member, Job, JobGroup
|
||||||
@@ -8,45 +10,56 @@ class MemberForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = [
|
fields = [
|
||||||
'firstname',
|
'firstname', 'surname', 'nickname', 'mailaccount', 'role', 'description', 'image',
|
||||||
'surname',
|
'birthday', 'phone', 'address',
|
||||||
'nickname',
|
|
||||||
'mailaccount',
|
|
||||||
'role',
|
|
||||||
'description',
|
|
||||||
'image',
|
|
||||||
'birthday',
|
|
||||||
'phone',
|
|
||||||
'address'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'description': CKEditorUploadingWidget(config_name='default')
|
'description': CKEditorUploadingWidget(config_name='default')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
'description': _("Beschreibung zu der Person"),
|
||||||
|
'image': _("Porträt"),
|
||||||
|
'birthday': _("Geburtstag"),
|
||||||
|
'phone': _("Telefonnummer"),
|
||||||
|
'address': _("Wohnadresse"),
|
||||||
|
}
|
||||||
|
|
||||||
|
help_texts = {
|
||||||
|
'image': _(
|
||||||
|
"Mindestgröße: 150*150 px, Verwendbare Formate: ..."
|
||||||
|
),
|
||||||
|
'mailaccount': _(
|
||||||
|
"Die Mailadresse mit '@fet.at' angeben."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class JobForm(forms.ModelForm):
|
class JobForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Job
|
model = Job
|
||||||
fields = [
|
fields = ['name', 'shortterm', 'slug', 'job_group',]
|
||||||
'name',
|
|
||||||
'shortterm',
|
labels = {
|
||||||
'slug',
|
'shortterm': _("Kürzel der Tätigkeit"),
|
||||||
'job_group',
|
'job_group': _("Tätigkeitsbereich"),
|
||||||
]
|
}
|
||||||
|
|
||||||
|
|
||||||
class JobGroupForm(forms.ModelForm):
|
class JobGroupForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = JobGroup
|
model = JobGroup
|
||||||
fields = [
|
fields = ['name', 'shortterm', 'slug', 'description', 'is_pinned',]
|
||||||
'name',
|
|
||||||
'shortterm',
|
|
||||||
'slug',
|
|
||||||
'description',
|
|
||||||
'is_pinned',
|
|
||||||
]
|
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'description': CKEditorUploadingWidget(config_name='default')
|
'description': CKEditorUploadingWidget(config_name='default')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
'shortterm': _("Kürzel des Tätigkeitsbereichs"),
|
||||||
|
'description': _("Beschreibung des Tätigkeitsbereichs"),
|
||||||
|
'is_pinned': _(
|
||||||
|
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, damit es sofort ersichtlich ist."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,16 +77,21 @@ class JobGroupManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class Member(models.Model):
|
class Member(models.Model):
|
||||||
firstname = models.CharField(max_length=128)
|
firstname = models.CharField("Vorname", max_length=128)
|
||||||
surname = models.CharField(max_length=128)
|
surname = models.CharField("Nachname", max_length=128)
|
||||||
nickname = models.CharField(max_length=128)
|
nickname = models.CharField("Spitzname", max_length=128)
|
||||||
mailaccount = models.CharField(max_length=128)
|
mailaccount = models.CharField("Mailadresse", max_length=128)
|
||||||
|
|
||||||
class MemberRole(models.TextChoices):
|
class MemberRole(models.TextChoices):
|
||||||
ACTIVE = 'A', _('Active')
|
ACTIVE = 'A', _('Active')
|
||||||
PENSION = 'P', _('Pension')
|
PENSION = 'P', _('Pension')
|
||||||
|
|
||||||
role = models.CharField(max_length=1, choices=MemberRole.choices, default=MemberRole.ACTIVE)
|
role = models.CharField(
|
||||||
|
"Rolle",
|
||||||
|
max_length=1,
|
||||||
|
choices=MemberRole.choices,
|
||||||
|
default=MemberRole.ACTIVE,
|
||||||
|
)
|
||||||
|
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
image = ThumbnailerImageField(upload_to='uploads/members/image/')
|
image = ThumbnailerImageField(upload_to='uploads/members/image/')
|
||||||
@@ -132,14 +137,14 @@ class JobGroup(models.Model):
|
|||||||
|
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
is_pinned = models.BooleanField(default=False)
|
is_pinned = models.BooleanField(verbose_name="ANGEHEFTET", default=False)
|
||||||
|
|
||||||
# Managers
|
# Managers
|
||||||
all_jobgroups = JobGroupManager()
|
all_jobgroups = JobGroupManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Tätigkeit-Gruppierung"
|
verbose_name = "Tätigkeitsbereich"
|
||||||
verbose_name_plural = "Tätigkeit-Gruppierungen"
|
verbose_name_plural = "Tätigkeitsbereiche"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from django.contrib import admin, auth, messages
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Post, Event, News, FetMeeting
|
from .models import Post, Event, News, FetMeeting
|
||||||
from .forms import MyPostForm, MyEventForm, MyNewsForm, MyFetMeetingForm
|
from .forms import PostForm, EventForm, NewsForm, FetMeetingForm
|
||||||
from documents.api import createPadifNotExists
|
from documents.api import createPadifNotExists
|
||||||
|
|
||||||
import taggit.admin
|
import taggit.admin
|
||||||
@@ -57,8 +57,8 @@ def make_fetmeeting(self, request, queryset):
|
|||||||
make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
||||||
|
|
||||||
|
|
||||||
class MyPostAdmin(admin.ModelAdmin):
|
class PostAdmin(admin.ModelAdmin):
|
||||||
form = MyPostForm
|
form = PostForm
|
||||||
model = Post
|
model = Post
|
||||||
list_filter = ['is_pinned', 'is_hidden']
|
list_filter = ['is_pinned', 'is_hidden']
|
||||||
list_display = ['title', 'slug', 'public_date', 'is_pinned', 'is_hidden']
|
list_display = ['title', 'slug', 'public_date', 'is_pinned', 'is_hidden']
|
||||||
@@ -95,8 +95,8 @@ class MyPostAdmin(admin.ModelAdmin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class MyEventAdmin(MyPostAdmin):
|
class EventAdmin(PostAdmin):
|
||||||
form = MyEventForm
|
form = EventForm
|
||||||
model = Event
|
model = Event
|
||||||
list_filter = ['is_pinned']
|
list_filter = ['is_pinned']
|
||||||
list_display = ['title', 'slug', 'event_start', 'public_date', 'is_pinned']
|
list_display = ['title', 'slug', 'event_start', 'public_date', 'is_pinned']
|
||||||
@@ -104,23 +104,19 @@ class MyEventAdmin(MyPostAdmin):
|
|||||||
actions = [make_fetmeeting]
|
actions = [make_fetmeeting]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Event, MyEventAdmin)
|
class NewsAdmin(PostAdmin):
|
||||||
|
form = NewsForm
|
||||||
|
|
||||||
class MyNewsAdmin(MyPostAdmin):
|
|
||||||
form = MyNewsForm
|
|
||||||
model = News
|
model = News
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(News, MyNewsAdmin)
|
class FetMeetingAdmin(EventAdmin):
|
||||||
|
form = FetMeetingForm
|
||||||
|
|
||||||
class MyFetMeetingAdmin(MyEventAdmin):
|
|
||||||
form = MyFetMeetingForm
|
|
||||||
model = FetMeeting
|
model = FetMeeting
|
||||||
list_filter = []
|
list_filter = []
|
||||||
list_display = ['title', 'slug', 'event_start', 'public_date']
|
list_display = ['title', 'slug', 'event_start', 'public_date']
|
||||||
actions = []
|
actions = []
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(FetMeeting, MyFetMeetingAdmin)
|
admin.site.register(Event, EventAdmin)
|
||||||
|
admin.site.register(News, NewsAdmin)
|
||||||
|
admin.site.register(FetMeeting, FetMeetingAdmin)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from taggit.models import Tag
|
|||||||
from .models import Post, Event, News, FetMeeting
|
from .models import Post, Event, News, FetMeeting
|
||||||
|
|
||||||
|
|
||||||
class MyPostForm(forms.ModelForm):
|
class PostForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Post
|
model = Post
|
||||||
fields = ['title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date']
|
fields = ['title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date']
|
||||||
@@ -21,28 +21,37 @@ class MyPostForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class MyNewsForm(MyPostForm):
|
class NewsForm(PostForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = News
|
model = News
|
||||||
fields = [
|
fields = [
|
||||||
'title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date',
|
'title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date',
|
||||||
'is_pinned', 'is_hidden',
|
'is_pinned', 'is_hidden',
|
||||||
]
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _('Titel des Posts'),
|
'title': _("Titel"),
|
||||||
'image': _('Hintergrundbild des Posts'),
|
'subtitle': _("Untertitel"),
|
||||||
'body': _('Beschreibung des Posts'),
|
'image': _("Hintergrundbild"),
|
||||||
'author': _('Autor'),
|
'body': _("Text"),
|
||||||
'public_date': _('Veröffentlichung'),
|
'author': _("Autor"),
|
||||||
'is_pinned': _('Post anheften'),
|
'public_date': _("Veröffentlichung"),
|
||||||
'is_hidden': _('Post verstecken'),
|
'is_pinned': _("Post anheften"),
|
||||||
|
'is_hidden': _("Post verstecken"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
|
'tags': _(
|
||||||
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
|
),
|
||||||
|
'image': _(
|
||||||
|
"Verwendbare Formate: ..."
|
||||||
|
),
|
||||||
'is_pinned': _(
|
'is_pinned': _(
|
||||||
'Dieser Post soll an die Startseite als erster Post angeheftet werden.'
|
"Dieser Post soll an die Startseite als erster Post angeheftet werden."
|
||||||
),
|
),
|
||||||
'is_hidden': _(
|
'is_hidden': _(
|
||||||
'Dieser Post soll im News Feed nicht auftauchen, z.B. Impressum.'
|
"Dieser Post soll im News Feed nicht auftauchen, z.B. Impressum."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,27 +61,36 @@ class MyNewsForm(MyPostForm):
|
|||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
|
|
||||||
|
|
||||||
class MyEventForm(MyPostForm):
|
class EventForm(PostForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Event
|
model = Event
|
||||||
fields = [
|
fields = [
|
||||||
'title', 'subtitle', 'tags', 'image', 'body', 'event_start', 'event_end',
|
'title', 'subtitle', 'tags', 'image', 'body', 'event_start', 'event_end',
|
||||||
'event_place', 'slug', 'author', 'public_date', 'is_pinned',
|
'event_place', 'slug', 'author', 'public_date', 'is_pinned',
|
||||||
]
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _('Titel des Events'),
|
'title': _("Titel"),
|
||||||
'image': _('Hintergrundbild des Posts'),
|
'subtitle': _("Untertitel"),
|
||||||
'body': _('Beschreibung des Events'),
|
'image': _("Hintergrundbild"),
|
||||||
'event_start': _('Start des Events'),
|
'body': _("Text"),
|
||||||
'event_end': _('Ende des Events'),
|
'event_start': _("Start des Events"),
|
||||||
'event_place': _('Ort des Events'),
|
'event_end': _("Ende des Events"),
|
||||||
'author': _('Autor'),
|
'event_place': _("Ort des Events"),
|
||||||
'public_date': _('Veröffentlichung'),
|
'author': _("Autor"),
|
||||||
'is_pinned': _('Event anheften'),
|
'public_date': _("Veröffentlichung"),
|
||||||
|
'is_pinned': _("Event anheften"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
|
'tags': _(
|
||||||
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
|
),
|
||||||
|
'image': _(
|
||||||
|
"Verwendbare Formate: "
|
||||||
|
),
|
||||||
'is_pinned': _(
|
'is_pinned': _(
|
||||||
'Dieses Event soll an die Startseite als erster Post angeheftet werden.'
|
"Dieses Event soll an die Startseite als erster Post angeheftet werden."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,20 +106,25 @@ class MyEventForm(MyPostForm):
|
|||||||
self.fields['event_place'].required = True
|
self.fields['event_place'].required = True
|
||||||
|
|
||||||
|
|
||||||
class MyFetMeetingForm(MyEventForm):
|
class FetMeetingForm(EventForm):
|
||||||
# agenda_html = forms.CharField(widget = forms.TextInput())
|
# agenda_html = forms.CharField(widget = forms.TextInput())
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FetMeeting
|
model = FetMeeting
|
||||||
fields = ['event_start', 'event_end', 'tags', 'has_agenda', 'has_protocol']
|
fields = ['event_start', 'event_end', 'tags', 'has_agenda', 'has_protocol']
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'event_start': _('Start der Sitzung'),
|
'event_start': _("Start der Sitzung"),
|
||||||
'event_end': _('Ende der Sitzung'),
|
'event_end': _("Ende der Sitzung"),
|
||||||
'has_agenda': _('Agenda'),
|
'has_agenda': _("Agenda"),
|
||||||
'has_protocol': _('Protokoll'),
|
'has_protocol': _("Protokoll"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'has_agenda': _('Agenda zur Sitzung hinzufügen.'),
|
'tags': _(
|
||||||
'has_protocol': _('Protokoll zur Sitzung hinzufügen.'),
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
|
),
|
||||||
|
'has_agenda': _("Agenda zur Sitzung hinzufügen."),
|
||||||
|
'has_protocol': _("Protokoll zur Sitzung hinzufügen."),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Post(models.Model):
|
|||||||
legacy_id = models.IntegerField(null=True)
|
legacy_id = models.IntegerField(null=True)
|
||||||
legacy_rubrik_id = models.IntegerField(null=True)
|
legacy_rubrik_id = models.IntegerField(null=True)
|
||||||
# Titel des Posts
|
# Titel des Posts
|
||||||
title = models.CharField(max_length=200)
|
title = models.CharField(verbose_name="Titel", max_length=200)
|
||||||
subtitle = models.CharField(max_length=500, null=True, blank=True)
|
subtitle = models.CharField(max_length=500, null=True, blank=True)
|
||||||
|
|
||||||
# Slug = Text Basierter url bestandteil zb Fetsitzung 22.1.2020 --> fetsitzung_22_1_2020 für Url
|
# Slug = Text Basierter url bestandteil zb Fetsitzung 22.1.2020 --> fetsitzung_22_1_2020 für Url
|
||||||
@@ -57,7 +57,7 @@ class Post(models.Model):
|
|||||||
|
|
||||||
tags = TaggableManager(blank=True)
|
tags = TaggableManager(blank=True)
|
||||||
# Datum ab dem etwas öffentlich sein soll
|
# Datum ab dem etwas öffentlich sein soll
|
||||||
public_date = models.DateField('date published', null=True, blank=True, default=timezone.now)
|
public_date = models.DateField(verbose_name="Veröffentlichung", null=True, blank=True, default=timezone.now)
|
||||||
|
|
||||||
imported_from = models.CharField(max_length=200, null=True, blank=True)
|
imported_from = models.CharField(max_length=200, null=True, blank=True)
|
||||||
|
|
||||||
@@ -75,8 +75,8 @@ class Post(models.Model):
|
|||||||
is_hidden = models.BooleanField(verbose_name="UNSICHTBAR", default=False)
|
is_hidden = models.BooleanField(verbose_name="UNSICHTBAR", default=False)
|
||||||
|
|
||||||
# Zusatz Info wenn ein Event gepostet wird
|
# Zusatz Info wenn ein Event gepostet wird
|
||||||
event_start = models.DateTimeField('Event Start', null=True, blank=True)
|
event_start = models.DateTimeField(verbose_name="Event Start", null=True, blank=True)
|
||||||
event_end = models.DateTimeField('Event Ende', null=True, blank=True)
|
event_end = models.DateTimeField(verbose_name="Event Ende", null=True, blank=True)
|
||||||
event_place = models.CharField(max_length=200, null=True, blank=True)
|
event_place = models.CharField(max_length=200, null=True, blank=True)
|
||||||
|
|
||||||
# Dokumente v.a. fuer Sitzungen
|
# Dokumente v.a. fuer Sitzungen
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class PostSerializer(serializers.HyperlinkedModelSerializer):
|
|||||||
'event_start',
|
'event_start',
|
||||||
'event_end',
|
'event_end',
|
||||||
'is_hidden',
|
'is_hidden',
|
||||||
'agenda_html'
|
'agenda_html',
|
||||||
|
'has_agenda',
|
||||||
# 'author',
|
# 'author',
|
||||||
]
|
]
|
||||||
extra_kwargs={
|
extra_kwargs={
|
||||||
|
|||||||
@@ -38,16 +38,7 @@ def tags(request, tag=""):
|
|||||||
featured_post = Post.objects.get_visible_articles().filter(slug=tag).first()
|
featured_post = Post.objects.get_visible_articles().filter(slug=tag).first()
|
||||||
members = []
|
members = []
|
||||||
|
|
||||||
job_names, slug_list = JobMember.jobs.get_job_names(slug=tag)
|
job_members = JobMember.active_member.get_all_by_slug(slug=tag)
|
||||||
|
|
||||||
if job_names:
|
|
||||||
active_members = JobMember.active_member.get_members_of_job(job_names=job_names)
|
|
||||||
|
|
||||||
for idx, item in enumerate(job_names):
|
|
||||||
if active_members[idx]:
|
|
||||||
members.append(
|
|
||||||
(job_names[idx], active_members[idx], tag + "#" + slug_list[idx])
|
|
||||||
)
|
|
||||||
|
|
||||||
author_image = None
|
author_image = None
|
||||||
if featured_post:
|
if featured_post:
|
||||||
@@ -60,7 +51,7 @@ def tags(request, tag=""):
|
|||||||
"posts": posts,
|
"posts": posts,
|
||||||
"author_image": author_image,
|
"author_image": author_image,
|
||||||
"featured_post": featured_post,
|
"featured_post": featured_post,
|
||||||
"members": members,
|
"job_members": job_members,
|
||||||
"tags_list": None,
|
"tags_list": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,29 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .forms import TaskListForm
|
from .forms import TaskAdminForm, TaskListForm
|
||||||
from .models import Task, TaskList
|
from .models import Task, TaskList
|
||||||
|
|
||||||
|
|
||||||
class TaskAdmin(admin.ModelAdmin):
|
class TaskAdmin(admin.ModelAdmin):
|
||||||
|
form = TaskAdminForm
|
||||||
model = Task
|
model = Task
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
'fields': (
|
'fields': (
|
||||||
'title',
|
'title',
|
||||||
'task_list',
|
'task_list',
|
||||||
|
'assigned_to',
|
||||||
'due_date',
|
'due_date',
|
||||||
'completed',
|
'completed',
|
||||||
'completed_date',
|
'completed_date',
|
||||||
'assigned_to',
|
|
||||||
'note',
|
'note',
|
||||||
'priority',
|
'priority',
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
list_display = (
|
|
||||||
'title',
|
list_display = ['title', 'task_list', 'assigned_to', 'due_date', 'completed', 'priority']
|
||||||
'task_list',
|
|
||||||
'completed',
|
|
||||||
'priority',
|
|
||||||
'due_date',
|
|
||||||
'assigned_to',
|
|
||||||
)
|
|
||||||
list_filter = ('task_list', )
|
list_filter = ('task_list', )
|
||||||
ordering = ('priority', )
|
|
||||||
search_fields = ('title', )
|
search_fields = ('title', )
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
|
|||||||
@@ -10,6 +10,27 @@ class DateInput(forms.DateInput):
|
|||||||
input_type = 'date'
|
input_type = 'date'
|
||||||
|
|
||||||
|
|
||||||
|
class TaskAdminForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Task
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
'title': _('Titel'),
|
||||||
|
'task_list': _('Aufgabenbereich'),
|
||||||
|
'due_date': _('Fälligkeit'),
|
||||||
|
'completed': _('Abgeschlossen'),
|
||||||
|
'completed_date': _('Datum der Fertigstellung'),
|
||||||
|
'assigned_to': _('Zuweisen an'),
|
||||||
|
'note': _('Notizen'),
|
||||||
|
'priority': _('Priorität'),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
|
self.fields['assigned_to'].empty_label = "Alle"
|
||||||
|
|
||||||
|
|
||||||
class TaskForm(forms.ModelForm):
|
class TaskForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Task
|
model = Task
|
||||||
@@ -40,4 +61,13 @@ class TaskForm(forms.ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class TaskListForm(forms.ModelForm):
|
class TaskListForm(forms.ModelForm):
|
||||||
users = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=FilteredSelectMultiple("User", is_stacked=False))
|
users = forms.ModelMultipleChoiceField(
|
||||||
|
label="Benutzer",
|
||||||
|
help_text="Es können nur die Benutzer ausgewählt werden, die sich auf der Homepage angemeldet haben.",
|
||||||
|
queryset=User.objects.all(),
|
||||||
|
widget=FilteredSelectMultiple("User", is_stacked=False)
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = TaskList
|
||||||
|
fields = '__all__'
|
||||||
|
|||||||
@@ -13,18 +13,19 @@ class TaskQuerySet(models.QuerySet):
|
|||||||
class TaskManager(models.Manager):
|
class TaskManager(models.Manager):
|
||||||
def get_tasks(self, user, completed, task_list, all_tasks):
|
def get_tasks(self, user, completed, task_list, all_tasks):
|
||||||
# None ... assigned to all users
|
# None ... assigned to all users
|
||||||
qs_comp = self.get_queryset().get_ordered().filter(assigned_to=user)
|
qs = self.get_queryset().get_ordered().filter(assigned_to__id=user)
|
||||||
|
|
||||||
if all_tasks:
|
if all_tasks:
|
||||||
qs_comp |= self.get_queryset().get_ordered().filter(Q(assigned_to=None) & Q(task_list__users=user))
|
qs_tmp = self.get_queryset().get_ordered().filter(Q(assigned_to=None) & Q(task_list__users__id__exact=user))
|
||||||
|
qs = (qs | qs_tmp).distinct()
|
||||||
|
|
||||||
if not completed:
|
if not completed:
|
||||||
qs_comp = qs_comp.filter(completed=completed)
|
qs = qs.filter(completed=completed)
|
||||||
|
|
||||||
if task_list:
|
if task_list:
|
||||||
qs_comp = qs_comp.filter(task_list=task_list)
|
qs = qs.filter(task_list=task_list)
|
||||||
|
|
||||||
return qs_comp
|
return qs
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return TaskQuerySet(self.model, using=self._db)
|
return TaskQuerySet(self.model, using=self._db)
|
||||||
@@ -38,39 +39,48 @@ class TaskList(models.Model):
|
|||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Aufgabenbereich"
|
||||||
|
verbose_name_plural = "Aufgabenbereiche"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Task(models.Model):
|
class Task(models.Model):
|
||||||
title = models.CharField(max_length=140)
|
title = models.CharField(verbose_name="Titel", max_length=140)
|
||||||
task_list = models.ForeignKey(TaskList, on_delete=models.CASCADE, null=True)
|
task_list = models.ForeignKey(TaskList, verbose_name="Aufgabenbereich", on_delete=models.CASCADE, null=True)
|
||||||
|
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
due_date = models.DateField(blank=True, null=True)
|
due_date = models.DateField(verbose_name="Fälligkeit", blank=True, null=True)
|
||||||
|
|
||||||
completed = models.BooleanField(default=False)
|
completed = models.BooleanField(verbose_name="Abgeschlossen", default=False)
|
||||||
completed_date = models.DateField(blank=True, null=True)
|
completed_date = models.DateField(blank=True, null=True)
|
||||||
|
|
||||||
created_by = models.ForeignKey(
|
created_by = models.ForeignKey(
|
||||||
settings.AUTH_USER_MODEL,
|
User,
|
||||||
related_name="todo_created_by",
|
related_name="created_by",
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
assigned_to = models.ForeignKey(
|
assigned_to = models.ForeignKey(
|
||||||
settings.AUTH_USER_MODEL,
|
User,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
related_name="todo_assigned_to",
|
related_name="assigned_to",
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
|
verbose_name="Zugewiesen an",
|
||||||
)
|
)
|
||||||
|
|
||||||
note = models.TextField(blank=True, null=True)
|
note = models.TextField(verbose_name="Notizen", blank=True, null=True)
|
||||||
priority = models.PositiveIntegerField(blank=True, null=True)
|
priority = models.PositiveIntegerField(verbose_name="Priorität", blank=True, null=True)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
taskmanager = TaskManager()
|
taskmanager = TaskManager()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Aufgabe"
|
||||||
|
verbose_name_plural = "Aufgaben"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="grid-x">
|
<div class="grid-x">
|
||||||
{% for member in members %}
|
{% for member in members %}
|
||||||
<div class="cell large-2 medium-3 small-6">
|
<div class="cell large-2 medium-3 small-6">
|
||||||
<h2>{{member.surname}}</h2>
|
<h2>{{member.firstname}} {{member.surname}}</h2>
|
||||||
{% include 'members/partials/_member.html' %}
|
{% include 'members/partials/_member.html' %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -34,35 +34,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div class="grid-x">
|
|
||||||
<div class="cell medium-8">
|
|
||||||
<h1>{{ post.title|tags_to_url }}</h1>
|
<h1>{{ post.title|tags_to_url }}</h1>
|
||||||
<strong>{{ post.subtitle|default_if_none:" "|tags_to_url }}</strong>
|
<strong>{{ post.subtitle|default_if_none:" "|tags_to_url }}</strong>
|
||||||
<span class="nav fa fa-chevron-right fa-3x"></span>
|
|
||||||
<br>
|
<br>
|
||||||
<a href="{% url 'posts.show' next %}">Nächster Artikel</a><br>
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-8">
|
||||||
<div class="cell medium-4">
|
|
||||||
{% include 'posts/partials/_date_box.html' %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Start: {{ post.event_start }}<br>
|
|
||||||
Ende: {{ post.event_end }}<br>
|
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
|
||||||
|
|
||||||
{% if post.has_agenda %}
|
|
||||||
<a href="{{ ep_agenda_link }}">Agenda</a><br>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if post.has_protocol %}
|
|
||||||
<a href="{{ ep_protocol_link }}">Protokoll</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<br>------<br>
|
|
||||||
<a href="{% url "admin:posts_news_change" post.id %}">Bearbeiten</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
{% for tag in post.get_tagnames %}
|
{% for tag in post.get_tagnames %}
|
||||||
{{ tag|tags_to_url }}
|
{{ tag|tags_to_url }}
|
||||||
@@ -77,6 +53,25 @@
|
|||||||
{{ post.body|safe|add_internal_links|tags_to_url }}
|
{{ post.body|safe|add_internal_links|tags_to_url }}
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cell medium-4">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
|
||||||
|
{% if post.has_agenda %}
|
||||||
|
<a href="{{ ep_agenda_link }}">Agenda</a><br>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if post.has_protocol %}
|
||||||
|
<a href="{{ ep_protocol_link }}">Protokoll</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Start: {{ post.event_start }}<br>
|
||||||
|
Ende: {{ post.event_end }}<br>
|
||||||
|
<a href="{% url 'posts.show' next %}">Nächster Artikel </a><span class="nav fa fa-chevron-right fa-1x"></span><br>
|
||||||
|
{% include 'posts/partials/_date_box.html' %}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid-x grid-margin-x">
|
<div class="grid-x grid-margin-x">
|
||||||
|
|||||||
@@ -37,23 +37,32 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
{% for member in members %}
|
<!-- show job lists in a job group -->
|
||||||
<h2>{{member.0}}<a class="headerlink" href="/members/jobs/{{member.2}}" title="Permalink to {{member.2}}"> #</a></h2>
|
{% regroup job_members by job.name as all_jobmem_list %}
|
||||||
|
|
||||||
|
{% for jobmem in all_jobmem_list %}
|
||||||
|
|
||||||
|
<div class="padding-top-1 padding-left-1 padding-bottom-1 padding-right-1" style="background-color: white;">
|
||||||
|
|
||||||
|
<h2>{{jobmem.grouper}}<a class="headerlink" href="#{{jobmem.list.0.job.slug}}" title="Permalink to {{jobmem.grouper}}"> #</a></h2>
|
||||||
|
<b>Aktuelle Mitglieder:</b>
|
||||||
|
|
||||||
<div class="grid-x">
|
<div class="grid-x">
|
||||||
{% for mem in member.1 %}
|
|
||||||
|
|
||||||
{% with member=mem.member %}
|
{% for jm in jobmem.list %}
|
||||||
|
{% with member=jm.member %}
|
||||||
<div class="medium-3 large-2 small-6 cell">
|
<div class="medium-3 large-2 small-6 cell">
|
||||||
<h2>{{member.surname}}</h2>
|
<h2>{{jm.member.firstname}} {{jm.member.surname}}</h2>
|
||||||
{% include 'members/partials/_member.html' %}
|
{% include 'members/partials/_member.html' %}
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
|||||||
Reference in New Issue
Block a user