add file uploads to post
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from django.contrib import admin, auth, messages
|
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, FileUpload
|
||||||
from .forms import PostForm, EventForm, NewsForm, FetMeetingForm
|
from .forms import PostForm, EventForm, NewsForm, FetMeetingForm
|
||||||
from documents.api import createPadifNotExists
|
from documents.api import createPadifNotExists
|
||||||
|
|
||||||
@@ -58,6 +58,13 @@ def make_fetmeeting(self, request, queryset):
|
|||||||
make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
||||||
|
|
||||||
|
|
||||||
|
class FileUploadInline(admin.TabularInline):
|
||||||
|
model = FileUpload
|
||||||
|
extra = 0
|
||||||
|
verbose_name = "Dokument"
|
||||||
|
verbose_name_plural = "Dokumentensammlung"
|
||||||
|
|
||||||
|
|
||||||
class PostAdmin(admin.ModelAdmin):
|
class PostAdmin(admin.ModelAdmin):
|
||||||
form = PostForm
|
form = PostForm
|
||||||
model = Post
|
model = Post
|
||||||
@@ -101,6 +108,12 @@ class PostAdmin(admin.ModelAdmin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class NewsAdmin(PostAdmin):
|
||||||
|
form = NewsForm
|
||||||
|
model = News
|
||||||
|
inlines = (FileUploadInline,)
|
||||||
|
|
||||||
|
|
||||||
class EventAdmin(PostAdmin):
|
class EventAdmin(PostAdmin):
|
||||||
form = EventForm
|
form = EventForm
|
||||||
model = Event
|
model = Event
|
||||||
@@ -110,11 +123,6 @@ class EventAdmin(PostAdmin):
|
|||||||
actions = [make_fetmeeting]
|
actions = [make_fetmeeting]
|
||||||
|
|
||||||
|
|
||||||
class NewsAdmin(PostAdmin):
|
|
||||||
form = NewsForm
|
|
||||||
model = News
|
|
||||||
|
|
||||||
|
|
||||||
class FetMeetingAdmin(EventAdmin):
|
class FetMeetingAdmin(EventAdmin):
|
||||||
form = FetMeetingForm
|
form = FetMeetingForm
|
||||||
model = FetMeeting
|
model = FetMeeting
|
||||||
|
|||||||
@@ -28,17 +28,17 @@ def create_pad_for_post(slug, typ="agenda"):
|
|||||||
"Creates a Etherpad Pad and returns EtherpadKey"
|
"Creates a Etherpad Pad and returns EtherpadKey"
|
||||||
print("creatingpadforpost")
|
print("creatingpadforpost")
|
||||||
try:
|
try:
|
||||||
agenda_key = createPadifNotExists(slug + "-" + typ)
|
etherpad_key = createPadifNotExists(slug + "-" + typ)
|
||||||
except URLError as error:
|
except URLError as error:
|
||||||
request_logger.info(
|
request_logger.info(
|
||||||
"""%s konnte von dem Slug '%s' nicht erstellt werden.
|
"%s konnte von dem Slug '%s' nicht erstellt werden. Error: %s",
|
||||||
Error: %s""",
|
|
||||||
typ,
|
typ,
|
||||||
slug,
|
slug,
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
return agenda_key
|
|
||||||
|
return etherpad_key
|
||||||
|
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
@@ -59,30 +59,24 @@ class Category(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Post(models.Model):
|
class Post(models.Model):
|
||||||
# id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
# legacy id is for the posts from the old website
|
||||||
legacy_id = models.IntegerField(null=True, blank=True)
|
legacy_id = models.IntegerField(null=True, blank=True)
|
||||||
legacy_rubrik_id = models.IntegerField(null=True, blank=True)
|
|
||||||
# Titel des Posts
|
|
||||||
title = models.CharField(verbose_name="Titel", 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)
|
||||||
|
tags = TaggableManager(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
|
||||||
slug = models.SlugField(unique=True, blank=True)
|
slug = models.SlugField(unique=True, blank=True)
|
||||||
# Body Text Artikel Text soll später mit WYSIWG Editor bearbeitet werden
|
|
||||||
body = models.TextField(null=True, blank=True)
|
|
||||||
# Ein Haupt Bild für den Post
|
|
||||||
image = models.ImageField(null=True, blank=True)
|
|
||||||
# Wer hat das geschrieben
|
|
||||||
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
|
|
||||||
|
|
||||||
tags = TaggableManager(blank=True)
|
body = models.TextField(null=True, blank=True)
|
||||||
# Datum ab dem etwas öffentlich sein soll
|
image = models.ImageField(null=True, blank=True)
|
||||||
|
|
||||||
|
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
public_date = models.DateField(
|
public_date = models.DateField(
|
||||||
verbose_name="Veröffentlichung", null=True, blank=True, default=timezone.now
|
verbose_name="Veröffentlichung", null=True, blank=True, default=timezone.now
|
||||||
)
|
)
|
||||||
|
|
||||||
imported_from = models.CharField(max_length=200, null=True, blank=True)
|
|
||||||
|
|
||||||
__choices = [("N", _("News")), ("E", _("Event")), ("F", _("FetMeeting"))]
|
__choices = [("N", _("News")), ("E", _("Event")), ("F", _("FetMeeting"))]
|
||||||
post_type = models.CharField(max_length=1, choices=__choices, editable=True)
|
post_type = models.CharField(max_length=1, choices=__choices, editable=True)
|
||||||
|
|
||||||
@@ -92,14 +86,12 @@ class Post(models.Model):
|
|||||||
# post is hidden from newsfeed (e.g. about)
|
# post is hidden from newsfeed (e.g. about)
|
||||||
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
|
# addional infos for events
|
||||||
event_start = models.DateTimeField(
|
event_start = models.DateTimeField(verbose_name="Event Start", null=True, blank=True)
|
||||||
verbose_name="Event Start", null=True, blank=True
|
|
||||||
)
|
|
||||||
event_end = models.DateTimeField(verbose_name="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
|
# protocol for fet meeting
|
||||||
has_protocol = models.BooleanField(default=False)
|
has_protocol = models.BooleanField(default=False)
|
||||||
has_agenda = models.BooleanField(default=False)
|
has_agenda = models.BooleanField(default=False)
|
||||||
protocol_key = models.CharField(max_length=200, null=True, blank=True)
|
protocol_key = models.CharField(max_length=200, null=True, blank=True)
|
||||||
@@ -109,6 +101,10 @@ class Post(models.Model):
|
|||||||
date_modified = models.DateTimeField(auto_now=True)
|
date_modified = models.DateTimeField(auto_now=True)
|
||||||
date_created = models.DateTimeField(auto_now_add=True)
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
# useless (-_-)
|
||||||
|
legacy_rubrik_id = models.IntegerField(null=True, blank=True)
|
||||||
|
imported_from = models.CharField(max_length=200, null=True, blank=True)
|
||||||
|
|
||||||
# Managers
|
# Managers
|
||||||
objects = PostManager()
|
objects = PostManager()
|
||||||
articles = ArticleManager()
|
articles = ArticleManager()
|
||||||
@@ -228,9 +224,6 @@ class Post(models.Model):
|
|||||||
return image.url
|
return image.url
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
# def key(self):
|
|
||||||
# return self.slug or self.id
|
|
||||||
|
|
||||||
def find_an_image(self):
|
def find_an_image(self):
|
||||||
"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
|
||||||
@@ -243,10 +236,6 @@ class Post(models.Model):
|
|||||||
if len(posts1) > 0:
|
if len(posts1) > 0:
|
||||||
return posts1.get().image
|
return posts1.get().image
|
||||||
|
|
||||||
# posts2=self.tags.similar_objects()
|
|
||||||
# for p in posts2:
|
|
||||||
# if p.image is not None:
|
|
||||||
# return p.image
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -351,34 +340,6 @@ class FetMeeting(Event):
|
|||||||
|
|
||||||
return slug
|
return slug
|
||||||
|
|
||||||
# def __get_agenda_key(self):
|
|
||||||
# if not self.slug:
|
|
||||||
# return None##
|
|
||||||
#
|
|
||||||
# try:
|
|
||||||
# agenda_key = createPadifNotExists(self.slug + "-agenda")
|
|
||||||
# except Exception as error:
|
|
||||||
# raise ValidationError(
|
|
||||||
# _("Die Agenda konnte nicht erstellt werden. Error: %(error)s"),
|
|
||||||
# params={"error": str(error)},
|
|
||||||
# ) from error
|
|
||||||
#
|
|
||||||
# return agenda_key
|
|
||||||
|
|
||||||
# def __get_protocol_key(self):
|
|
||||||
# if not self.slug:
|
|
||||||
# return None#
|
|
||||||
#
|
|
||||||
# try:
|
|
||||||
# protocol_key = createPadifNotExists(self.slug + "-protocol")
|
|
||||||
# except URLError as error:
|
|
||||||
# raise ValidationError(
|
|
||||||
# _("Das Protokoll konnte nicht erstellt werden. Error: %(error)s"),
|
|
||||||
# params={"error": str(error)},
|
|
||||||
# ) from error#
|
|
||||||
#
|
|
||||||
# return protocol_key
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
@@ -406,3 +367,14 @@ class FetMeeting(Event):
|
|||||||
self.event_end = self.event_start + timedelta(hours=2)
|
self.event_end = self.event_start + timedelta(hours=2)
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class FileUpload(models.Model):
|
||||||
|
title = models.CharField(verbose_name="Titel", max_length=200)
|
||||||
|
file_field = models.FileField(verbose_name="Dokument", upload_to="uploads/posts/files/")
|
||||||
|
post = models.ForeignKey(Post, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
objects = models.Manager()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ from documents.api import get_pad_link
|
|||||||
from documents.etherpadlib import add_ep_cookie
|
from documents.etherpadlib import add_ep_cookie
|
||||||
from members.models import Member, JobMember
|
from members.models import Member, JobMember
|
||||||
|
|
||||||
|
from .models import Post, FetMeeting, FileUpload
|
||||||
from .models import Post, FetMeeting
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -74,6 +73,8 @@ def show(request, id=None):
|
|||||||
elif id != "" and id is not None:
|
elif id != "" and id is not None:
|
||||||
p = Post.objects.get(slug=(id))
|
p = Post.objects.get(slug=(id))
|
||||||
|
|
||||||
|
files = deque(FileUpload.objects.filter(post=p))
|
||||||
|
|
||||||
post_author = Member.all_members.filter(username=p.author).first()
|
post_author = Member.all_members.filter(username=p.author).first()
|
||||||
author_image = None
|
author_image = None
|
||||||
author = None
|
author = None
|
||||||
@@ -112,6 +113,7 @@ def show(request, id=None):
|
|||||||
|
|
||||||
context = {
|
context = {
|
||||||
"post": p,
|
"post": p,
|
||||||
|
"files": files,
|
||||||
"author": author,
|
"author": author,
|
||||||
"author_image": author_image,
|
"author_image": author_image,
|
||||||
"next": get_next_dict(p),
|
"next": get_next_dict(p),
|
||||||
|
|||||||
@@ -79,9 +79,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="cell medium-4">
|
<div class="cell medium-4">
|
||||||
<a href="{% url 'posts.show' next %}">Nächster Artikel <span class="nav fa fa-chevron-right fa-1x"></span></a><br>
|
<a href="{% url 'posts.show' next %}">Nächster Artikel <span class="nav fa fa-chevron-right fa-1x"></span></a><br>
|
||||||
<hr>
|
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
|
<hr>
|
||||||
|
|
||||||
{% if post.has_agenda %}
|
{% if post.has_agenda %}
|
||||||
<a href="{{ ep_agenda_link }}">Agenda</a><br>
|
<a href="{{ ep_agenda_link }}">Agenda</a><br>
|
||||||
@@ -101,10 +101,10 @@
|
|||||||
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}">Bearbeiten</a>
|
<a href="{% url 'admin:posts_fetmeeting_change' post.id %}">Bearbeiten</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<hr>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if post.event_start %}
|
{% if post.event_start %}
|
||||||
|
<hr>
|
||||||
Start: {{ post.event_start|date:"d. F Y" }} {{ post.event_start|time:"H:i" }}<br>
|
Start: {{ post.event_start|date:"d. F Y" }} {{ post.event_start|time:"H:i" }}<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if post.event_end %}
|
{% if post.event_end %}
|
||||||
@@ -114,6 +114,21 @@
|
|||||||
{% if post.event_start %}
|
{% if post.event_start %}
|
||||||
{% include 'posts/partials/_date_box.html' %}
|
{% include 'posts/partials/_date_box.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if files %}
|
||||||
|
<hr>
|
||||||
|
Dokumente:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for file in files %}
|
||||||
|
<li><a href="{{file.file_field.url}}" target="_blank">{{file.title}}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user