views/program: allow changing program cover

This commit is contained in:
Chris Tactic 2023-11-21 15:28:59 +01:00
parent 9e952735b8
commit 1d9dc4628a
4 changed files with 55 additions and 76 deletions

View File

@ -1,19 +1,6 @@
{% extends "aircox/basepage_detail.html" %} {% extends "aircox/basepage_detail.html" %}
{% load static i18n humanize honeypot aircox %} {% load static i18n humanize honeypot aircox %}
{% comment %}
Base template used to display a Page
Context:
- page: page
- parent: parent page
{% endcomment %}
{% block header_crumbs %}
{{ block.super }}
{% if page.category %}
{% if parent %} / {% endif %} {{ page.category.title }}
{% endif %}
{% endblock %}
{% block top-nav-tools %} {% block top-nav-tools %}
<a class="navbar-item" href="{% url 'program-detail' object.slug %}" <a class="navbar-item" href="{% url 'program-detail' object.slug %}"
@ -27,65 +14,11 @@ Context:
{% block main %} {% block main %}
<form method="post">{% csrf_token %} <form method="post">{% csrf_token %}
{{ form.as_p }} <table>
<input type="submit" value="Update" class="button is-success"> {{ form.as_table }}
</form>
{{ block.super }}
{% block comments %}
{% if comments or comment_form %}
<section class="mt-6">
<h4 class="title is-4">{% translate "Comments" %}</h4>
{% for comment in comments %}
<div class="media box">
<div class="media-content">
<p>
<strong class="mr-2">{{ comment.nickname }}</strong>
<time datetime="{{ comment.date }}" title="{{ comment.date }}">
<small>{{ comment.date|naturaltime }}</small>
</time>
<br>
{{ comment.content }}
</p>
</div>
</div>
{% endfor %}
{% if comment_form %}
<form method="POST">
<h5 class="title is-5">{% translate "Post a comment" %}</h5>
{% csrf_token %}
{% render_honeypot_field "website" %} {% render_honeypot_field "website" %}
</table>
{% for field in comment_form %} <br/>
<div class="field is-horizontal"> <input type="submit" value="Update" class="button is-success">
<div class="field-label is-normal"> </form>
<label class="label">
{{ field.label_tag }}
</label>
</div>
<div class="field-body">
<div class="field">
<p class="control is-expanded">{{ field }}</p>
{% if field.errors %}
<p class="help is-danger">{{ field.errors }}</p>
{% endif %}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
</div>
{% endfor %}
<div class="has-text-right">
<button type="reset" class="button is-danger">{% translate "Reset" %}</button>
<button type="submit" class="button is-success">{% translate "Post comment" %}</button>
</div>
</form>
{% endif %}
</section>
{% endif %}
{% endblock %}
{% endblock %} {% endblock %}

View File

@ -1,5 +1,14 @@
import pytest import pytest
from django.urls import reverse from django.urls import reverse
from django.core.files.uploadedfile import SimpleUploadedFile
from aircox.models import Program
png_content = (
b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde"
+ b"\x00\x00\x00\x0cIDATx\x9cc`\xf8\xcf\x00\x00\x02\x02\x01\x00{\t\x81x\x00\x00\x00\x00IEND\xaeB`\x82"
)
@pytest.mark.django_db() @pytest.mark.django_db()
@ -15,3 +24,17 @@ def test_edit_program(user, client, program):
response = client.post(reverse("program-edit", kwargs={"pk": program.pk}), {"content": "foobar"}) response = client.post(reverse("program-edit", kwargs={"pk": program.pk}), {"content": "foobar"})
response = client.get(reverse("program-detail", kwargs={"slug": program.slug})) response = client.get(reverse("program-detail", kwargs={"slug": program.slug}))
assert b"foobar" in response.content assert b"foobar" in response.content
@pytest.mark.django_db()
def test_add_cover(user, client, program):
assert program.cover is None
user.groups.add(program.editors)
client.force_login(user)
cover = SimpleUploadedFile("cover1.png", png_content, content_type="image/png")
r = client.post(
reverse("program-edit", kwargs={"pk": program.pk}), {"content": "foobar", "new_cover": cover}, follow=True
)
assert r.status_code == 200
p = Program.objects.get(pk=program.pk)
assert "cover1.png" in p.cover.url

View File

@ -142,4 +142,7 @@ class PageDetailView(BasePageDetailView):
class PageUpdateView(BaseView, UpdateView): class PageUpdateView(BaseView, UpdateView):
pass context_object_name = "page"
def get_page(self):
return self.object

View File

@ -1,6 +1,8 @@
from django.contrib.auth.mixins import UserPassesTestMixin
from django.forms import ModelForm, ImageField
from django.urls import reverse from django.urls import reverse
from django.contrib.auth.mixins import UserPassesTestMixin from filer.models.imagemodels import Image
from ..models import Page, Program, StaticPage from ..models import Page, Program, StaticPage
from .mixins import ParentMixin from .mixins import ParentMixin
@ -32,9 +34,24 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
return super().get_sidebar_queryset().filter(parent=self.program) return super().get_sidebar_queryset().filter(parent=self.program)
class ProgramForm(ModelForm):
new_cover = ImageField(required=False)
class Meta:
model = Program
fields = ["content"]
def save(self, commit=True):
file_obj = self.cleaned_data["new_cover"]
if file_obj:
obj, _ = Image.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
self.instance.cover = obj
super().save(commit=commit)
class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView): class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
model = Program model = Program
fields = ["content"] form_class = ProgramForm
def get_sidebar_queryset(self): def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.program) return super().get_sidebar_queryset().filter(parent=self.program)
@ -43,6 +60,9 @@ class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
program = self.get_object() program = self.get_object()
return self.request.user.has_perm("aircox.%s" % program.change_permission_codename) return self.request.user.has_perm("aircox.%s" % program.change_permission_codename)
def get_success_url(self):
return reverse("program-detail", kwargs={"slug": self.get_object().slug})
class ProgramListView(PageListView): class ProgramListView(PageListView):
model = Program model = Program