Merge branch 'master' into etherpad

This commit is contained in:
2020-07-24 10:44:57 +00:00
26 changed files with 267 additions and 189 deletions

6
.gitignore vendored
View File

@@ -4,6 +4,8 @@
fet2020/files/* fet2020/files/*
fet2020/.env/* fet2020/.env/*
*.sqlite3 *.sqlite3
fet2020/posts/migrations/* fet2020/*/migrations/*
fet2020/members/migrations/*
.theia/* .theia/*
.flake8
migrate
run

View File

@@ -1,5 +1,5 @@
from etherpad_lite import EtherpadLiteClient from etherpad_lite import EtherpadLiteClient
from django.conf import settings # from django.conf import settings
from datetime import datetime, timedelta from datetime import datetime, timedelta
t = datetime.now() + timedelta(days=1) t = datetime.now() + timedelta(days=1)
@@ -9,4 +9,3 @@ with open("/srv/andis_test/etherpad-lite/etherpad-lite/APIKEY.txt","r") as f:
epc = EtherpadLiteClient(base_params={'apikey': k, }, base_url="http://localhost:9001/api") epc = EtherpadLiteClient(base_params={'apikey': k, }, base_url="http://localhost:9001/api")
a = epc.createAuthorIfNotExistsFor(name="andis", authorMapper="andis") a = epc.createAuthorIfNotExistsFor(name="andis", authorMapper="andis")
g = epc.createGroupIfNotExistsFor(groupMapper="fet") g = epc.createGroupIfNotExistsFor(groupMapper="fet")

View File

@@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Document from .models import Document
from django.urls import path from django.urls import path
from django.contrib.auth import views as auth_views # from django.contrib.auth import views as auth_views
from django.shortcuts import render from django.shortcuts import render
@@ -11,12 +11,10 @@ class DocumentModelAdmin(admin.ModelAdmin):
return render(request, "admin/documents/preview.html") return render(request, "admin/documents/preview.html")
def get_urls(self): def get_urls(self):
urls = super().get_urls() # urls = super().get_urls()
select_list_url = [ path("<int:id>/preview", self.admin_site.admin_view(self.my_view), select_list_url = [
name='preview'), path("<int:id>/preview", self.admin_site.admin_view(self.my_view), name='preview'),
path("preview", self.admin_site.admin_view(self.my_view), path("preview", self.admin_site.admin_view(self.my_view), name='preview')
name='preview')
] ]
return select_list_url # + urls return select_list_url # + urls

View File

@@ -1,7 +1,6 @@
from django.apps import AppConfig from django.apps import AppConfig
# from django.contrib.admin.apps import AdminConfig
class DocumentsConfig(AppConfig): class DocumentsConfig(AppConfig):
name = 'documents' name = 'documents'
from django.contrib.admin.apps import AdminConfig

View File

@@ -1,8 +1,6 @@
from django.db import models from django.db import models
# Create your models here. # Create your models here.
class Document(models.Model): class Document(models.Model):
key = models.CharField(max_length=200, primary_key=True) key = models.CharField(max_length=200, primary_key=True)

View File

@@ -1,3 +1,3 @@
from django.test import TestCase # from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@@ -1,6 +1,7 @@
import documents.views as views import documents.views as views
from django.urls import path from django.urls import path
urlpatterns = [ urlpatterns = [
path("document/<id>", views.document) path("document/<id>", views.document)
] ]

View File

@@ -3,36 +3,37 @@ from django.shortcuts import render
# Create your views here. # Create your views here.
from django.http import HttpResponseRedirect # from django.http import HttpResponseRedirect
from django.template import RequestContext # from django.template import RequestContext
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext_lazy as _ # from django.utils.translation import ugettext_lazy as _
import urllib # import urllib
from urllib.parse import urlparse from urllib.parse import urlparse
from .models import Document # from .models import Document
from documents import epc from documents import epc
from documents import g as group from documents import g as group
SERVER_URL="http://etherpad.2020.fet.at/"
import datetime import datetime
SERVER_URL = "http://etherpad.2020.fet.at/"
@login_required @login_required
def document(request, id=None): def document(request, id=None):
"""Create and session and display an embedded pad """Create and session and display an embedded pad
""" """
# Initialize some needed values # Initialize some needed values
# pad = Document.objects.get(key=id) # pad = Document.objects.get(key=id)
padID = id padID = id
padLink = SERVER_URL + 'p/' + group["groupID"] + '$' + \ padLink = SERVER_URL + 'p/' + group["groupID"] + '$' + padID
padID
server = urlparse(SERVER_URL) server = urlparse(SERVER_URL)
author = epc.createAuthorIfNotExistsFor(name=str(request.user), authorMapper=str(request.user))['authorID'] author = epc.createAuthorIfNotExistsFor(
name=str(request.user),
authorMapper=str(request.user)
)['authorID']
# Create the session on the etherpad-lite side # Create the session on the etherpad-lite side
expires = datetime.datetime.utcnow() + datetime.timedelta( expires = datetime.datetime.utcnow() + datetime.timedelta(hours=3)
hours=3
)
epclient = epc epclient = epc
try: try:
@@ -49,15 +50,14 @@ def document(request, id=None):
'link': padLink, 'link': padLink,
'server': str(server), 'server': str(server),
'uname': str(request.user), 'uname': str(request.user),
'error': 'etherpad-lite session request returned:' + 'error': 'etherpad-lite session request returned:' + '"' + str(e) + '"'
'"' + str(e) + '"'
} }
) )
return response return response
# Set up the response # Set up the response
response = render(request, response = render(
request,
'documents/pad.html', 'documents/pad.html',
{ {
'pad': padID, 'pad': padID,
@@ -65,7 +65,8 @@ def document(request, id=None):
'server': str(server), 'server': str(server),
'uname': str(request.user), 'uname': str(request.user),
'error': False 'error': False
}#, context=(request) }
# context=(request)
) )
# Delete the existing session first # Delete the existing session first

View File

@@ -1,13 +1,18 @@
from django.contrib.auth.models import User # from django.contrib.auth.models import User
from django.contrib.auth.middleware import RemoteUserMiddleware from django.contrib.auth.middleware import RemoteUserMiddleware
import django # import django
# import logging # import logging
# logger=logging.getLogger("django.request") # logger=logging.getLogger("django.request")
class FETHeaderMiddleware(RemoteUserMiddleware): class FETHeaderMiddleware(RemoteUserMiddleware):
header = "Remote-User" header = "Remote-User"
def process_request(self, request): def process_request(self, request):
request.META[self.header]=request.META.get(self.header, request.headers.get(self.header,None)) request.META[self.header] = request.META.get(
self.header,
request.headers.get(self.header, None)
)
super().process_request(request) super().process_request(request)
if request.user.is_authenticated: if request.user.is_authenticated:
request.user.is_admin = True request.user.is_admin = True

View File

@@ -12,6 +12,23 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
import os import os
# Prints and logs are written to console
# TODO: Change before release
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'DEBUG',
},
}
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -33,10 +50,9 @@ DATA_UPLOAD_MAX_MEMORY_SIZE = 1024*1024*1024
CKEDITOR_UPLOAD_PATH = 'upload' CKEDITOR_UPLOAD_PATH = 'upload'
INSTALLED_APPS = [ INSTALLED_APPS = [
'posts.apps.PostsConfig',
'members.apps.MembersConfig',
'documents.apps.DocumentsConfig', 'documents.apps.DocumentsConfig',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
@@ -48,7 +64,8 @@ INSTALLED_APPS = [
'rest_framework', 'rest_framework',
'django_filters', 'django_filters',
'django_static_jquery_ui', 'django_static_jquery_ui',
'django.contrib.admindocs' 'posts.apps.PostsConfig',
'members.apps.MembersConfig',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@@ -67,7 +84,10 @@ ROOT_URLCONF = 'fet2020.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),os.path.join(BASE_DIR, 'templates_design1')], 'DIRS': [
os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'templates_design1')
],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@@ -143,8 +163,6 @@ STATICFILES_DIRS = [
MEDIA_ROOT = os.path.join(BASE_DIR, 'files/') MEDIA_ROOT = os.path.join(BASE_DIR, 'files/')
MEDIA_URL = '/files/' MEDIA_URL = '/files/'
TAGGIT_FORCE_LOWERCASE = True TAGGIT_FORCE_LOWERCASE = True
CKEDITOR_CONFIGS = { CKEDITOR_CONFIGS = {
@@ -162,5 +180,4 @@ CKEDITOR_CONFIGS = {
}, },
], ],
} }
} }

View File

@@ -1,22 +1,27 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse # from django.http import HttpResponse
from collections import deque from collections import deque
from posts.models import Post from posts.models import Post
def index(request): def index(request):
posts = deque(Post.article_objects.all()) posts = deque(Post.article_objects.all())
l=len(posts)
def get_tags(lst): def get_tags(lst):
for p in lst: for p in lst:
for t in list(p.tags.names()): for t in list(p.tags.names()):
yield "#" + t yield "#" + t
t = set(t for t in get_tags(posts)) t = set(t for t in get_tags(posts))
if l>=1: if len(posts) >= 1:
featured_post = posts.popleft() featured_post = posts.popleft()
else: else:
featured_post = 0 featured_post = 0
return render(request, 'home.html',{'posts':posts, 'featured_post':featured_post, "tags_list": ", ".join(t)}) context = {
'posts': posts,
'featured_post': featured_post,
'tags_list': ", ".join(t)
}
return render(request, 'home.html', context)

View File

@@ -21,14 +21,17 @@ class MemberRoleFilter(admin.SimpleListFilter):
elif self.value() == 'P': elif self.value() == 'P':
return queryset.filter(role='P') return queryset.filter(role='P')
class JobMemberInline(admin.TabularInline): class JobMemberInline(admin.TabularInline):
model = JobMember model = JobMember
extra = 0 extra = 0
class JobOverviewInline(JobMemberInline): class JobOverviewInline(JobMemberInline):
verbose_name = "Tätigkeit" verbose_name = "Tätigkeit"
verbose_name_plural = "Tätigkeitsübersicht" verbose_name_plural = "Tätigkeitsübersicht"
class ActiveMemberInline(JobMemberInline): class ActiveMemberInline(JobMemberInline):
verbose_name = "Mitglied" verbose_name = "Mitglied"
verbose_name_plural = "Aktive Mitglieder Liste" verbose_name_plural = "Aktive Mitglieder Liste"
@@ -36,6 +39,7 @@ class ActiveMemberInline(JobMemberInline):
def get_queryset(self, request): def get_queryset(self, request):
return JobMember.active_member.all() return JobMember.active_member.all()
class InactiveMemberInline(JobMemberInline): class InactiveMemberInline(JobMemberInline):
verbose_name = "Mitglied" verbose_name = "Mitglied"
verbose_name_plural = "Inaktive Mitglieder Liste" verbose_name_plural = "Inaktive Mitglieder Liste"
@@ -43,10 +47,12 @@ class InactiveMemberInline(JobMemberInline):
def get_queryset(self, request): def get_queryset(self, request):
return JobMember.inactive_member.all() return JobMember.inactive_member.all()
class JobInline(admin.TabularInline): class JobInline(admin.TabularInline):
model = Job model = Job
extra = 0 extra = 0
class MyMemberAdmin(admin.ModelAdmin): class MyMemberAdmin(admin.ModelAdmin):
form = MyMemberForm form = MyMemberForm
model = Member model = Member
@@ -60,8 +66,10 @@ class MyMemberAdmin(admin.ModelAdmin):
obj.author = request.user obj.author = request.user
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
admin.site.register(Member, MyMemberAdmin) admin.site.register(Member, MyMemberAdmin)
class MyJobAdmin(admin.ModelAdmin): class MyJobAdmin(admin.ModelAdmin):
form = MyJobForm form = MyJobForm
model = Job model = Job
@@ -74,8 +82,10 @@ class MyJobAdmin(admin.ModelAdmin):
obj.author = request.user obj.author = request.user
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
admin.site.register(Job, MyJobAdmin) admin.site.register(Job, MyJobAdmin)
class MyJobGroupAdmin(admin.ModelAdmin): class MyJobGroupAdmin(admin.ModelAdmin):
form = MyJobGroupForm form = MyJobGroupForm
model = JobGroup model = JobGroup
@@ -88,4 +98,5 @@ class MyJobGroupAdmin(admin.ModelAdmin):
obj.author = request.user obj.author = request.user
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
admin.site.register(JobGroup, MyJobGroupAdmin) admin.site.register(JobGroup, MyJobGroupAdmin)

View File

@@ -20,14 +20,27 @@ class MyMemberForm(forms.ModelForm):
'address' 'address'
] ]
widgets = {'description': CKEditorUploadingWidget(config_name='default')} widgets = {
'description': CKEditorUploadingWidget(config_name='default')
}
class MyJobForm(forms.ModelForm): class MyJobForm(forms.ModelForm):
class Meta: class Meta:
model = Job model = Job
fields = ['name', 'shortterm', 'slug', 'job_group', 'description', 'image'] fields = [
'name',
'shortterm',
'slug',
'job_group',
'description',
'image'
]
widgets = {
'description': CKEditorUploadingWidget(config_name='default')
}
widgets = {'description': CKEditorUploadingWidget(config_name='default')}
class MyJobGroupForm(forms.ModelForm): class MyJobGroupForm(forms.ModelForm):
class Meta: class Meta:

View File

@@ -6,7 +6,7 @@ from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
import uuid # import uuid
from datetime import timedelta from datetime import timedelta
@@ -15,10 +15,12 @@ class MemberManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(role='A') return super().get_queryset().filter(role='A')
class PensionManager(models.Manager): class PensionManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(role='P') return super().get_queryset().filter(role='P')
class ActiveMemberManager(models.Manager): class ActiveMemberManager(models.Manager):
''' '''
return a list of active member, and members who are still working return a list of active member, and members who are still working
@@ -27,12 +29,9 @@ class ActiveMemberManager(models.Manager):
date_today = timezone.now().date() date_today = timezone.now().date()
return super().get_queryset().filter( return super().get_queryset().filter(
Q(member__role='A') & Q(member__role='A')
( & (Q(job_end__gt=date_today) | Q(job_end__isnull=True)))
Q(job_end__gt=date_today) |
Q(job_end__isnull=True)
)
)
class InactiveMemberManager(models.Manager): class InactiveMemberManager(models.Manager):
''' '''
@@ -42,12 +41,9 @@ class InactiveMemberManager(models.Manager):
date_today = timezone.now().date() date_today = timezone.now().date()
return super().get_queryset().filter( return super().get_queryset().filter(
Q(member__role='P') | Q(member__role='P')
( | (Q(job_end__lt=date_today + timedelta(days=1)) & Q(job_end__isnull=False)))
Q(job_end__lt=date_today + timedelta(days=1)) &
Q(job_end__isnull=False)
)
)
class Member(models.Model): class Member(models.Model):
firstname = models.CharField(max_length=128) firstname = models.CharField(max_length=128)
@@ -57,7 +53,7 @@ class Member(models.Model):
__choices = [ __choices = [
('A', _('Active')), ('A', _('Active')),
('P', _('Pension')) ('P', _('Pension')),
] ]
role = models.CharField(max_length=1, choices=__choices, default='A') role = models.CharField(max_length=1, choices=__choices, default='A')
@@ -70,8 +66,15 @@ class Member(models.Model):
"Phone number must be entered in the format: " "Phone number must be entered in the format: "
"+999999999'. Up to 15 digits allowed." "+999999999'. Up to 15 digits allowed."
)) ))
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message=phone_error_msg) phone_regex = RegexValidator(
phone = models.CharField(validators=[phone_regex], max_length=17, blank=True) regex=r'^\+?1?\d{9,15}$',
message=phone_error_msg,
)
phone = models.CharField(
validators=[phone_regex],
max_length=17,
blank=True,
)
address = models.TextField(null=True, blank=True) address = models.TextField(null=True, blank=True)
@@ -90,6 +93,7 @@ class Member(models.Model):
def __str__(self): def __str__(self):
return self.firstname + " " + self.surname return self.firstname + " " + self.surname
class MemberSerializer(serializers.HyperlinkedModelSerializer): class MemberSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = Member model = Member
@@ -100,9 +104,10 @@ class MemberSerializer(serializers.HyperlinkedModelSerializer):
'mailaccount', 'mailaccount',
'role', 'role',
'description', 'description',
'image' 'image',
] ]
class JobGroup(models.Model): class JobGroup(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
shortterm = models.CharField(max_length=128) shortterm = models.CharField(max_length=128)
@@ -111,6 +116,7 @@ class JobGroup(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
class Job(models.Model): class Job(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
shortterm = models.CharField(max_length=128) shortterm = models.CharField(max_length=128)
@@ -139,6 +145,7 @@ class Job(models.Model):
def __str__(self): def __str__(self):
return self.shortterm return self.shortterm
class JobMember(models.Model): class JobMember(models.Model):
member = models.ForeignKey( member = models.ForeignKey(
Member, Member,

View File

@@ -1,3 +1,3 @@
from django.test import TestCase # from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@@ -1,5 +1,5 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse # from django.http import HttpResponse
from collections import deque from collections import deque
@@ -7,7 +7,7 @@ from .models import Member, Job, JobMember, JobGroup, MemberSerializer
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework import permissions from rest_framework import permissions
from django_filters.rest_framework import DjangoFilterBackend # from django_filters.rest_framework import DjangoFilterBackend
def index(request): def index(request):
@@ -26,6 +26,7 @@ def index(request):
return render(request, 'members/index.html', context) return render(request, 'members/index.html', context)
class MemberViewSet(viewsets.ModelViewSet): class MemberViewSet(viewsets.ModelViewSet):
""" """
API endpoint that allows users to be viewed or edited. API endpoint that allows users to be viewed or edited.

View File

@@ -1,5 +1,5 @@
import django.contrib.auth.admin # import django.contrib.auth.admin
import django.contrib.auth.models # import django.contrib.auth.models
import taggit.admin import taggit.admin
from django.contrib import admin, auth from django.contrib import admin, auth
@@ -33,21 +33,27 @@ class MyPostAdmin(admin.ModelAdmin):
"jquery-ui/jquery-ui.min.js", "jquery-ui/jquery-ui.min.js",
] ]
class MyEventAdmin(MyPostAdmin): class MyEventAdmin(MyPostAdmin):
form = MyEventForm form = MyEventForm
model = Event model = Event
list_display = ['title', 'subtitle', 'slug', 'event_start', 'public_date'] list_display = ['title', 'subtitle', 'slug', 'event_start', 'public_date']
admin.site.register(Event, MyEventAdmin) admin.site.register(Event, MyEventAdmin)
class MyNewsAdmin(MyPostAdmin): class MyNewsAdmin(MyPostAdmin):
form = MyNewsForm form = MyNewsForm
model = News model = News
admin.site.register(News, MyNewsAdmin) admin.site.register(News, MyNewsAdmin)
class MyFetMeetingAdmin(MyEventAdmin): class MyFetMeetingAdmin(MyEventAdmin):
form = MyFetMeetingForm form = MyFetMeetingForm
model = FetMeeting model = FetMeeting
admin.site.register(FetMeeting, MyFetMeetingAdmin) admin.site.register(FetMeeting, MyFetMeetingAdmin)

View File

@@ -17,6 +17,7 @@ class MyPostForm(forms.ModelForm):
'js/tag_completion.js', # to get a list for tag autocompletion via ajax 'js/tag_completion.js', # to get a list for tag autocompletion via ajax
) )
class MyNewsForm(MyPostForm): class MyNewsForm(MyPostForm):
class Meta: class Meta:
model = News model = News
@@ -27,6 +28,7 @@ class MyNewsForm(MyPostForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # to get the self.fields set super().__init__(*args, **kwargs) # to get the self.fields set
class MyEventForm(MyPostForm): class MyEventForm(MyPostForm):
class Meta: class Meta:
model = Event model = Event
@@ -44,6 +46,7 @@ class MyEventForm(MyPostForm):
if 'event_place' in self.fields: if 'event_place' in self.fields:
self.fields['event_place'].required = True self.fields['event_place'].required = True
class MyFetMeetingForm(MyEventForm): class MyFetMeetingForm(MyEventForm):
class Meta: class Meta:
model = FetMeeting model = FetMeeting

View File

@@ -9,7 +9,7 @@ from django.utils.translation import gettext_lazy as _
from taggit.managers import TaggableManager from taggit.managers import TaggableManager
# from ckeditor_uploader import RichTextUploadingField # from ckeditor_uploader import RichTextUploadingField
import uuid # import uuid
import re import re
from rest_framework import serializers from rest_framework import serializers
@@ -27,6 +27,7 @@ class PostManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset() return super().get_queryset()
class ArticleManager(models.Manager): class ArticleManager(models.Manager):
""" """
Provide a query set only for "Article" Provide a query set only for "Article"
@@ -35,10 +36,12 @@ class ArticleManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(Q(post_type='E') | Q(post_type='N')) return super().get_queryset().filter(Q(post_type='E') | Q(post_type='N'))
class NewsManager(models.Manager): class NewsManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(~Q(is_event=True)) return super().get_queryset().filter(~Q(is_event=True))
class EventManager(models.Manager): class EventManager(models.Manager):
""" """
Provide a query set only for "Events" Provide a query set only for "Events"
@@ -47,6 +50,7 @@ class EventManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(Q(is_event=True) & Q(post_type='E')) return super().get_queryset().filter(Q(is_event=True) & Q(post_type='E'))
class FetMeetingManager(models.Manager): class FetMeetingManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(Q(post_type='F')) return super().get_queryset().filter(Q(post_type='F'))
@@ -72,6 +76,7 @@ class Category(models.Model):
verbose_name = "Category" verbose_name = "Category"
verbose_name_plural = "Categories" verbose_name_plural = "Categories"
class Post(models.Model): class Post(models.Model):
# id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
legacy_id = models.IntegerField(null=True) legacy_id = models.IntegerField(null=True)
@@ -145,7 +150,8 @@ class Post(models.Model):
"find an image via another post" "find an image via another post"
# TODO: Explain why this image is selected on save of the image # TODO: Explain why this image is selected on save of the image
# Query all posts that have a slug that equals one of the tags # Query all posts that have a slug that equals one of the tags
posts1 = Post.objects.filter(slug__in=self.tags.names()).filter(image__isnull=False)[0:1].all() posts1 = Post.objects.filter(
slug__in=self.tags.names()).filter(image__isnull=False)[0:1].all()
if len(posts1) > 0: if len(posts1) > 0:
return posts1.get().image return posts1.get().image
@@ -172,6 +178,7 @@ class Post(models.Model):
def __str__(self): def __str__(self):
return "Post (%s, %s): %s " % (self.slug, self.public_date.strftime("%d.%m.%Y"), self.title) return "Post (%s, %s): %s " % (self.slug, self.public_date.strftime("%d.%m.%Y"), self.title)
class PostSerializer(serializers.HyperlinkedModelSerializer): class PostSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = Post model = Post
@@ -186,9 +193,10 @@ class PostSerializer(serializers.HyperlinkedModelSerializer):
'image', 'image',
'event_start', 'event_start',
'event_end', 'event_end',
'is_fetsitzung' 'is_fetsitzung',
] ]
class News(Post): class News(Post):
objects = NewsManager() objects = NewsManager()
@@ -204,6 +212,7 @@ class News(Post):
super().save(*args, **kwargs) super().save(*args, **kwargs)
class Event(Post): class Event(Post):
objects = EventManager() objects = EventManager()
@@ -218,6 +227,7 @@ class Event(Post):
super().save(*args, **kwargs) super().save(*args, **kwargs)
class FetMeeting(Event): class FetMeeting(Event):
objects = FetMeetingManager() objects = FetMeetingManager()

View File

@@ -5,9 +5,8 @@ from django.utils.safestring import mark_safe
register = template.Library() register = template.Library()
@register.filter(is_safe=True) @register.filter(is_safe=True)
@stringfilter @stringfilter
def tags_to_url(value): def tags_to_url(value):
# return "Tag to url: %s" % value # return "Tag to url: %s" % value
return mark_safe(re.sub(r'\#([\d\w-]+)', '<a href="/posts/t/\g<1>">#\g<1></a>', value)) return mark_safe(re.sub(r'\#([\d\w-]+)', r'<a href="/posts/t/\g<1>">#\g<1></a>', value))

View File

@@ -1,3 +1,3 @@
from django.test import TestCase # from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@@ -1,13 +1,13 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse, HttpResponseServerError
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from django.core.cache import cache # from django.core.cache import cache
from django.utils.text import slugify from django.utils.text import slugify
from django.utils import timezone from django.utils import timezone
from taggit.models import Tag from taggit.models import Tag
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework import permissions # from rest_framework import permissions
from .models import Post, PostSerializer from .models import Post, PostSerializer
@@ -20,7 +20,9 @@ from collections import deque
def index(request): def index(request):
posts = deque(Post.objects.order_by('-public_date').all()) posts = deque(Post.objects.order_by('-public_date').all())
f = lambda p: p.tags
def f(p):
return p.tags
t = map(f, posts) t = map(f, posts)
return render(request, 'posts/index.html', {"posts": posts, "tags_list": t}) return render(request, 'posts/index.html', {"posts": posts, "tags_list": t})
@@ -34,7 +36,7 @@ def tags(request,tag=""):
def show(request, id=None): def show(request, id=None):
if id.isdigit() or id is int: if id.isdigit() or id is int:
p = Post.objects.get(id=int(id)) p = Post.objects.get(id=int(id))
elif id != "" and not id is None: elif id != "" and id is not None:
p = Post.objects.get(slug=(id)) p = Post.objects.get(slug=(id))
context = { context = {

View File

@@ -5,3 +5,4 @@ Pillow
djangorestframework djangorestframework
django-static-jquery-ui django-static-jquery-ui
docutils docutils
etherpad-lite