diff --git a/fet2020/fet2020/views.py b/fet2020/fet2020/views.py index 90432738..801d2e49 100644 --- a/fet2020/fet2020/views.py +++ b/fet2020/fet2020/views.py @@ -5,7 +5,7 @@ from posts.models import Post, FetMeeting, Event def index(request): - posts = deque(Post.article_objects.all()) + posts = deque(Post.articles.all()) def get_tags(lst): for p in lst: @@ -13,14 +13,21 @@ def index(request): yield "#" + t t = set(t for t in get_tags(posts)) - if len(posts) >= 1: - featured_post = posts.popleft() + + tmp = Post.articles.get_pinned_article() + if tmp: + # if a pinned post exists + featured_post = tmp[0] else: - featured_post = 0 + # if a pinned post does not exist, take the last published one. + if len(posts) >= 1: + featured_post = posts.popleft() + else: + featured_post = 0 context = { 'posts': posts, - 'events': Event.objects.get_five_events(), + 'events': Event.all_events.get_five_events(), 'featured_post': featured_post, 'featured_meeting': deque(FetMeeting.objects.get_meetings()), 'tags_list': ", ".join(t) diff --git a/fet2020/posts/admin.py b/fet2020/posts/admin.py index 76392422..a74e4de7 100644 --- a/fet2020/posts/admin.py +++ b/fet2020/posts/admin.py @@ -22,8 +22,8 @@ make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren" class MyPostAdmin(admin.ModelAdmin): form = MyPostForm model = Post - list_filter = ['is_event'] - list_display = ['title', 'subtitle', 'slug', 'public_date'] + list_filter = ['is_pinned'] + list_display = ['title', 'subtitle', 'slug', 'public_date', 'is_pinned'] ordering = ['-public_date'] def add_view(self, request, form_url='', extra_context=None): diff --git a/fet2020/posts/forms.py b/fet2020/posts/forms.py index 77efafa2..f4f2f723 100644 --- a/fet2020/posts/forms.py +++ b/fet2020/posts/forms.py @@ -21,7 +21,10 @@ class MyPostForm(forms.ModelForm): class MyNewsForm(MyPostForm): class Meta: model = News - fields = ['title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date'] + fields = [ + 'title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date', + 'is_pinned', + ] widgets = {'body': CKEditorUploadingWidget(config_name='default')} diff --git a/fet2020/posts/managers.py b/fet2020/posts/managers.py new file mode 100644 index 00000000..4678012b --- /dev/null +++ b/fet2020/posts/managers.py @@ -0,0 +1,73 @@ +from django.db import models +from django.db.models import Q +from django.utils import timezone + + +class PostManager(models.Manager): + def get_queryset(self): + return super().get_queryset() + + +class ArticleManager(models.Manager): + """ + Provide a query set only for "Article" + regular fet meetings should not be contained in the news stream + """ + def get_queryset(self): + return super().get_queryset().filter( + Q(post_type='E') + | Q(post_type='N') + ).order_by('-public_date') + + def get_pinned_article(self): + return self.get_queryset().filter(is_pinned=True) + + +class NewsManager(models.Manager): + """ + Provide a query set only for "News" + """ + def get_queryset(self): + return super().get_queryset().filter(post_type='N') + + +class AllEventManager(models.Manager): + """ + Provide a query set for all events ("Event" and "Fet Meeting") + """ + def get_queryset(self): + return super().get_queryset().filter(Q(post_type='E') | Q(post_type='F')) + + def get_five_events(self): + return self.get_queryset().order_by('-event_start')[:5] + + +class EventManager(models.Manager): + """ + Provide a query set only for "Events" + regular fet meetings should not be contained in the news stream + """ + def get_queryset(self): + return super().get_queryset().filter(post_type='E') + + +class FetMeetingManager(models.Manager): + """ + Provide a query set only for "Fet Meeting" + """ + def get_queryset(self): + return super().get_queryset().filter(post_type='F') + + def _get_future_events(self): + date_today = timezone.now() + return self.get_queryset().filter(event_start__gt=date_today).order_by('event_start') + + def _get_past_events(self): + date_today = timezone.now() + return self.get_queryset().filter(event_start__lt=date_today).order_by('-event_start') + + def get_meetings(self): + meetings = [] + meetings.append(self._get_future_events().first()) + meetings.append(self._get_past_events().first()) + return meetings diff --git a/fet2020/posts/models.py b/fet2020/posts/models.py index 40087432..04ec1f19 100644 --- a/fet2020/posts/models.py +++ b/fet2020/posts/models.py @@ -1,14 +1,16 @@ from django.contrib.auth.models import User from django.core.validators import ValidationError from django.db import models -from django.db.models import Q from django.urls import reverse from django.utils import timezone from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from members.models import Member from taggit.managers import TaggableManager -# import documents + +from .managers import ( + PostManager, ArticleManager, NewsManager, AllEventManager, EventManager, FetMeetingManager +) # from ckeditor_uploader import RichTextUploadingField @@ -22,83 +24,6 @@ import logging logger = logging.getLogger('posts') -############ -# MANAGERS # -############ - -class PostManager(models.Manager): - def get_queryset(self): - return super().get_queryset() - - -class ArticleManager(models.Manager): - """ - Provide a query set only for "Article" - regular fet meetings should not be contained in the news stream - """ - def get_queryset(self): - return super().get_queryset().filter( - Q(post_type='E') - | Q(post_type='N') - ).order_by('-public_date') - - -class NewsManager(models.Manager): - def get_queryset(self): - return super().get_queryset().filter(~Q(is_event=True)) - - -class EventManager(models.Manager): - """ - Provide a query set only for "Events" - regular fet meetings should not be contained in the news stream - """ - def get_queryset(self): - return super().get_queryset().filter( - Q(is_event=True) - & ~Q(post_type='F') - ).order_by('-public_date') - - def get_all_events(self): - date_today = timezone.now().date() - return super().get_queryset().filter( - Q(is_event=True) - & Q(event_start__gt=date_today) - ).order_by('-event_start') - - def get_five_events(self): - return super().get_queryset().filter( - Q(is_event=True) - ).order_by('-event_start')[:5] - - -class FetMeetingManager(models.Manager): - def get_queryset(self): - return super().get_queryset().filter(Q(post_type='F')) - - def _get_last_meeting(self): - date_today = timezone.now() - return self.get_queryset().filter( - Q(event_start__lt=date_today) - ).order_by('-event_start').first() - - def _get_next_meeting(self): - date_today = timezone.now() - return self.get_queryset().filter( - Q(event_start__gt=date_today) - ).order_by('event_start').first() - - def get_meetings(self): - meetings = [] - meetings.append(self._get_next_meeting()) - meetings.append(self._get_last_meeting()) - return meetings - - -########## -# MODELS # -########## - class Category(models.Model): # Titel des Posts title = models.CharField(max_length=200) @@ -146,7 +71,8 @@ class Post(models.Model): ] post_type = models.CharField(max_length=1, choices=__choices, editable=False) - is_event = models.BooleanField(default=False) + # post is pinned at main page + is_pinned = models.BooleanField(default=False) # Zusatz Info wenn ein Event gepostet wird event_start = models.DateTimeField('Event Start', null=True, blank=True) @@ -165,7 +91,7 @@ class Post(models.Model): # Managers objects = PostManager() - article_objects = ArticleManager() + articles = ArticleManager() def get_tags(self): """Returns assigned tags as a comma seperated list.""" @@ -269,7 +195,8 @@ class News(Post): class Event(Post): - objects = EventManager() + only_events = EventManager() + all_events = AllEventManager() class Meta: proxy = True @@ -292,8 +219,6 @@ class Event(Post): raise ValidationError(_('Das Ende des Events liegt vor dem Beginn.')) def save(self, *args, **kwargs): - self.is_event = True - if not self.post_type: self.post_type = 'E' diff --git a/fet2020/posts/views.py b/fet2020/posts/views.py index 4a1d1d9a..449218f8 100644 --- a/fet2020/posts/views.py +++ b/fet2020/posts/views.py @@ -108,7 +108,7 @@ def tag_complete(request): def get_next_dict(): # TODO: Docstring - posts = Post.article_objects.order_by('-public_date').values('slug') + posts = Post.articles.values('slug') print(posts) d = {} print(d)