fix
This commit is contained in:
commit
c79f040fa1
|
@ -1,7 +1,12 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.forms import ModelForm
|
from django.forms import ModelForm, ImageField, FileField
|
||||||
|
|
||||||
from .models import Comment
|
from ckeditor.fields import RichTextField
|
||||||
|
from filer.models.imagemodels import Image
|
||||||
|
from filer.models.filemodels import File
|
||||||
|
|
||||||
|
from aircox.models import Comment, Episode, Program
|
||||||
|
from aircox.controllers.sound_file import SoundFile
|
||||||
|
|
||||||
|
|
||||||
class CommentForm(ModelForm):
|
class CommentForm(ModelForm):
|
||||||
|
@ -16,3 +21,38 @@ class CommentForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Comment
|
model = Comment
|
||||||
fields = ["nickname", "email", "content"]
|
fields = ["nickname", "email", "content"]
|
||||||
|
|
||||||
|
|
||||||
|
class ProgramForm(ModelForm):
|
||||||
|
content = RichTextField()
|
||||||
|
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 EpisodeForm(ModelForm):
|
||||||
|
content = RichTextField()
|
||||||
|
new_podcast = FileField(required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Episode
|
||||||
|
fields = ["content"]
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
file_obj = self.cleaned_data["new_podcast"]
|
||||||
|
if file_obj:
|
||||||
|
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
||||||
|
sound_file = SoundFile(obj.path)
|
||||||
|
sound_file.sync(
|
||||||
|
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
|
||||||
|
)
|
||||||
|
super().save(commit=commit)
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -125,6 +125,7 @@ class Program(Page):
|
||||||
editors, created = Group.objects.get_or_create(name=self.editors_group_name)
|
editors, created = Group.objects.get_or_create(name=self.editors_group_name)
|
||||||
if created:
|
if created:
|
||||||
self.editors = editors
|
self.editors = editors
|
||||||
|
super().save()
|
||||||
permission, _ = Permission.objects.get_or_create(
|
permission, _ = Permission.objects.get_or_create(
|
||||||
name=f"change program {self.title}",
|
name=f"change program {self.title}",
|
||||||
codename=self.change_permission_codename,
|
codename=self.change_permission_codename,
|
||||||
|
@ -159,7 +160,6 @@ class Program(Page):
|
||||||
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
||||||
|
|
||||||
self.set_group_ownership()
|
self.set_group_ownership()
|
||||||
super().save(*kargs, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class ProgramChildQuerySet(PageQuerySet):
|
class ProgramChildQuerySet(PageQuerySet):
|
||||||
|
|
|
@ -81,6 +81,9 @@ class Station(models.Model):
|
||||||
max_length=64,
|
max_length=64,
|
||||||
default=_("Music stream"),
|
default=_("Music stream"),
|
||||||
)
|
)
|
||||||
|
legal_label = models.CharField(
|
||||||
|
_("Legal label"), max_length=64, blank=True, default="", help_text=_("Displayed at the bottom of pages.")
|
||||||
|
)
|
||||||
|
|
||||||
objects = StationQuerySet.as_manager()
|
objects = StationQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ Usefull context:
|
||||||
<div class="navs">
|
<div class="navs">
|
||||||
{% block nav %}
|
{% block nav %}
|
||||||
<nav class="nav primary" role="navigation" aria-label="main navigation">
|
<nav class="nav primary" role="navigation" aria-label="main navigation">
|
||||||
{% block nav-primary %}
|
{% block primary-nav %}
|
||||||
<a class="nav-brand" href="{% url "home" %}">
|
<a class="nav-brand" href="{% url "home" %}">
|
||||||
<img src="{{ station.logo.url }}">
|
<img src="{{ station.logo.url }}">
|
||||||
</a>
|
</a>
|
||||||
|
@ -60,7 +60,7 @@ Usefull context:
|
||||||
aria-label="{% translate "Main menu" %}">
|
aria-label="{% translate "Main menu" %}">
|
||||||
</a-switch>
|
</a-switch>
|
||||||
<div class="nav-menu">
|
<div class="nav-menu">
|
||||||
{% block nav-primary-menu %}
|
{% block primary-nav-menu %}
|
||||||
{% nav_items "top" css_class="nav-item" active_class="active" as items %}
|
{% nav_items "top" css_class="nav-item" active_class="active" as items %}
|
||||||
{% for item, render in items %}
|
{% for item, render in items %}
|
||||||
{{ render }}
|
{{ render }}
|
||||||
|
@ -71,11 +71,9 @@ Usefull context:
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a class="nav-item" href="{% url "profile" %}" target="new">
|
<a class="nav-item" href="{% url "logout" %}" title="{% translate "Disconnect" %}"
|
||||||
{% translate "Profile" %}
|
aria-label="{% translate "Disconnect" %}">
|
||||||
</a>
|
<i class="fa fa-power-off"></i>
|
||||||
<a class="nav-item" href="{% url 'logout' %}">
|
|
||||||
<i title="{% translate 'disconnect' %}" class="fa fa-power-off"></i>
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -98,8 +96,6 @@ Usefull context:
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% block header-container %}
|
{% block header-container %}
|
||||||
{% if page or cover or title %}
|
{% if page or cover or title %}
|
||||||
<header class="container header preview preview-header {% if cover %}has-cover{% endif %}">
|
<header class="container header preview preview-header {% if cover %}has-cover{% endif %}">
|
||||||
|
@ -146,6 +142,24 @@ Usefull context:
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer-container %}
|
||||||
|
<footer class="page-footer">
|
||||||
|
{% block footer %}
|
||||||
|
{% if request.station and request.station.legal_label %}
|
||||||
|
{{ request.station.legal_label }} —
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<a class="nav-item" href="{% url "profile" %}" target="new"
|
||||||
|
title="{% translate "Profile" %}">
|
||||||
|
<span class="small icon">
|
||||||
|
<i class="fa fa-account">
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
{% endblock %}
|
||||||
|
</footer>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% block player-container %}
|
{% block player-container %}
|
||||||
<div id="player">{% include "aircox/widgets/player.html" %}</div>
|
<div id="player">{% include "aircox/widgets/player.html" %}</div>
|
||||||
|
|
|
@ -4,15 +4,19 @@
|
||||||
{% if user.is_authenticated and can_edit %}
|
{% if user.is_authenticated and can_edit %}
|
||||||
{% with request.resolver_match.view_name as view_name %}
|
{% with request.resolver_match.view_name as view_name %}
|
||||||
|
|
||||||
{% if view_name in 'program-edit,bla' %}
|
{% if view_name in 'page-edit,program-edit,episode-edit' %}
|
||||||
<!--
|
<a href="{% url view_name|detail_view page.slug %}" target="_self">
|
||||||
<a href="{% url 'program-detail' page.slug %}" target="_self">
|
<small>
|
||||||
<span title="{% translate 'View' %} {{ page }}">{% translate 'View' %} 👁 </span>
|
<span title="{% translate 'View' %} {{ page }}">{% translate 'View' %} </span>
|
||||||
|
<i class="fa-regular fa-eye"></i>
|
||||||
|
</small>
|
||||||
</a>
|
</a>
|
||||||
-->
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{% url view_name|edit_view page.pk %}" target="_self">
|
<a href="{% url view_name|edit_view page.pk %}" target="_self">
|
||||||
<span title="{% translate 'Edit' %} {{ page }}">{% translate 'Edit' %} 🖉 </span>
|
<small>
|
||||||
|
<span title="{% translate 'Edit' %} {{ page }}">{% translate 'Edit' %} </span>
|
||||||
|
<i class="fa-solid fa-pencil"></i>
|
||||||
|
</small>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
<table>
|
<table>
|
||||||
{{ form.as_table }}
|
{{ form.as_table }}
|
||||||
{% render_honeypot_field "website" %}
|
{% render_honeypot_field "website" %}
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
<input type="submit" value="Update" class="button is-success">
|
<input type="submit" value="Update" class="button is-success">
|
||||||
|
<hr>
|
||||||
|
|
||||||
{% include "aircox/playlist_inline.html" %}
|
{% include "aircox/playlist_inline.html" %}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,23 @@
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<div>
|
<div>
|
||||||
<form method="post" enctype="multipart/form-data">{% csrf_token %}
|
<form method="post" enctype="multipart/form-data">{% csrf_token %}
|
||||||
<table>
|
{% csrf_token %}
|
||||||
{{ form.as_table }}
|
{% for field in form %}
|
||||||
{% render_honeypot_field "website" %}
|
<div class="field is-horizontal">
|
||||||
</table>
|
<label class="label">{{ field.label }}</label>
|
||||||
<br/>
|
<div class="control">{{ field }}</div>
|
||||||
<input type="submit" value="Update" class="button is-success">
|
</div>
|
||||||
|
{% 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 %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="has-text-right">
|
||||||
|
<button type="submit" class="button">{% translate "Update" %}</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -143,3 +143,8 @@ def do_verbose_name(obj, plural=False):
|
||||||
@register.filter(name="edit_view")
|
@register.filter(name="edit_view")
|
||||||
def do_edit_view(obj):
|
def do_edit_view(obj):
|
||||||
return "%s-edit" % obj.split("-")[0]
|
return "%s-edit" % obj.split("-")[0]
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name="detail_view")
|
||||||
|
def do_detail_view(obj):
|
||||||
|
return "%s-detail" % obj.split("-")[0]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from datetime import time, timedelta
|
from datetime import time, timedelta
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
@ -162,3 +163,10 @@ def tracks(episode, sound):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def user():
|
def user():
|
||||||
return User.objects.create_user(username="user1", password="bar")
|
return User.objects.create_user(username="user1", password="bar")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def png_content():
|
||||||
|
image_file = "{}/image.png".format(os.path.dirname(__file__))
|
||||||
|
with open(image_file, "rb") as fh:
|
||||||
|
return fh.read()
|
||||||
|
|
BIN
aircox/tests/image.png
Normal file
BIN
aircox/tests/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 B |
|
@ -7,12 +7,6 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from aircox.models import Program
|
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()
|
||||||
def test_edit_program(user, client, program):
|
def test_edit_program(user, client, program):
|
||||||
client.force_login(user)
|
client.force_login(user)
|
||||||
|
@ -29,7 +23,7 @@ def test_edit_program(user, client, program):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db()
|
@pytest.mark.django_db()
|
||||||
def test_add_cover(user, client, program):
|
def test_add_cover(user, client, program, png_content):
|
||||||
assert program.cover is None
|
assert program.cover is None
|
||||||
user.groups.add(program.editors)
|
user.groups.add(program.editors)
|
||||||
client.force_login(user)
|
client.force_login(user)
|
||||||
|
@ -58,16 +52,16 @@ def test_edit_tracklist(user, client, program, episode, tracks):
|
||||||
tracklist = [t.id for t in episode.track_set.all().order_by("position")]
|
tracklist = [t.id for t in episode.track_set.all().order_by("position")]
|
||||||
tracklist_details_reversed = [(t.id, t.artist, t.title) for t in episode.track_set.all().order_by("-position")]
|
tracklist_details_reversed = [(t.id, t.artist, t.title) for t in episode.track_set.all().order_by("-position")]
|
||||||
tracklist_details_reversed = list(chain(*tracklist_details_reversed))
|
tracklist_details_reversed = list(chain(*tracklist_details_reversed))
|
||||||
data = """{"website": [""], "content": ["foobar"], "new_podcast": [""], "form-TOTAL_FORMS": ["3"],
|
data = """{{"website": [""], "content": ["foobar"], "new_podcast": [""], "form-TOTAL_FORMS": ["3"],
|
||||||
"form-INITIAL_FORMS": ["3"], "form-MIN_NUM_FORMS": ["0"], "form-MAX_NUM_FORMS": ["1000"], "form-0-position": ["0"],
|
"form-INITIAL_FORMS": ["3"], "form-MIN_NUM_FORMS": ["0"], "form-MAX_NUM_FORMS": ["1000"], "form-0-position": ["0"],
|
||||||
"form-0-id": ["%s"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["%s"], "form-0-title": ["%s"],
|
"form-0-id": ["{}"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["{}"], "form-0-title": ["{}"],
|
||||||
"form-0-tags": [""], "form-0-album": [""], "form-0-year": [""], "form-1-position": ["1"], "form-1-id": ["%s"],
|
"form-0-tags": [""], "form-0-album": [""], "form-0-year": [""], "form-1-position": ["1"], "form-1-id": ["{}"],
|
||||||
"form-1-": ["", "", "", "", "", ""], "form-1-artist": ["%s"], "form-1-title": ["%s"], "form-1-tags": [""],
|
"form-1-": ["", "", "", "", "", ""], "form-1-artist": ["{}"], "form-1-title": ["{}"], "form-1-tags": [""],
|
||||||
"form-1-album": [""], "form-1-year": [""], "form-2-position": ["2"], "form-2-id": ["%s"], "form-2-": ["", "", "",
|
"form-1-album": [""], "form-1-year": [""], "form-2-position": ["2"], "form-2-id": ["{}"], "form-2-": ["", "", "",
|
||||||
"", "", ""], "form-2-artist": ["%s"], "form-2-title": ["%s"], "form-2-tags": [""], "form-2-album": [""],
|
"", "", ""], "form-2-artist": ["{}"], "form-2-title": ["{}"], "form-2-tags": [""], "form-2-album": [""],
|
||||||
"form-2-year": [""]}""" % tuple(
|
"form-2-year": [""]}}""".format(
|
||||||
tracklist_details_reversed
|
*tracklist_details_reversed
|
||||||
)
|
)
|
||||||
r = client.post(reverse("episode-edit", kwargs={"pk": episode.pk}), json.loads(data), follow=True)
|
r = client.post(reverse("episode-edit", kwargs={"pk": episode.pk}), json.loads(data), follow=True)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
assert [t.id for t in episode.track_set.all().order_by("position")] == list(reversed(tracklist))
|
assert set(episode.track_set.all().values_list("id", flat=True)) == set(tracklist)
|
||||||
|
|
|
@ -132,6 +132,6 @@ urls = [
|
||||||
views.errors.NoStationErrorView.as_view(),
|
views.errors.NoStationErrorView.as_view(),
|
||||||
name="errors-no-station",
|
name="errors-no-station",
|
||||||
),
|
),
|
||||||
path("gestion/", views.profile, name="profile"),
|
path(_("manage/"), views.ProfileView.as_view(), name="profile"),
|
||||||
path("accounts/profile/", views.profile, name="profile"),
|
path("accounts/profile/", views.ProfileView.as_view(), name="profile"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,7 +11,7 @@ from .page import (
|
||||||
PageDetailView,
|
PageDetailView,
|
||||||
PageListView,
|
PageListView,
|
||||||
)
|
)
|
||||||
from .profile import profile
|
from .profile import ProfileView
|
||||||
from .program import (
|
from .program import (
|
||||||
ProgramDetailView,
|
ProgramDetailView,
|
||||||
ProgramListView,
|
ProgramListView,
|
||||||
|
@ -40,7 +40,7 @@ __all__ = (
|
||||||
"BasePageListView",
|
"BasePageListView",
|
||||||
"PageDetailView",
|
"PageDetailView",
|
||||||
"PageListView",
|
"PageListView",
|
||||||
"profile",
|
"ProfileView",
|
||||||
"ProgramDetailView",
|
"ProgramDetailView",
|
||||||
"ProgramListView",
|
"ProgramListView",
|
||||||
"ProgramPageDetailView",
|
"ProgramPageDetailView",
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||||
from django.forms import ModelForm, FileField
|
|
||||||
from django.forms.models import modelformset_factory
|
from django.forms.models import modelformset_factory
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from aircox.forms import EpisodeForm
|
||||||
from filer.models.filemodels import File
|
from aircox.models import Episode, Program, StaticPage, Track
|
||||||
|
|
||||||
from aircox.controllers.sound_file import SoundFile
|
|
||||||
from aircox.models import Track
|
|
||||||
|
|
||||||
from ..filters import EpisodeFilters
|
from ..filters import EpisodeFilters
|
||||||
from ..models import Episode, Program, StaticPage
|
|
||||||
from .page import PageListView
|
from .page import PageListView
|
||||||
from .program import ProgramPageDetailView, BaseProgramMixin
|
from .program import ProgramPageDetailView, BaseProgramMixin
|
||||||
from .page import PageUpdateView
|
from .page import PageUpdateView
|
||||||
|
@ -53,25 +47,6 @@ class PodcastListView(EpisodeListView):
|
||||||
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
|
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
|
||||||
|
|
||||||
|
|
||||||
class EpisodeForm(ModelForm):
|
|
||||||
content = RichTextField()
|
|
||||||
new_podcast = FileField(required=False)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Episode
|
|
||||||
fields = ["content"]
|
|
||||||
|
|
||||||
def save(self, commit=True):
|
|
||||||
file_obj = self.cleaned_data["new_podcast"]
|
|
||||||
if file_obj:
|
|
||||||
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
|
|
||||||
sound_file = SoundFile(obj.path)
|
|
||||||
sound_file.sync(
|
|
||||||
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
|
|
||||||
)
|
|
||||||
super().save(commit=commit)
|
|
||||||
|
|
||||||
|
|
||||||
class EpisodeUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
|
class EpisodeUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
|
||||||
model = Episode
|
model = Episode
|
||||||
form_class = EpisodeForm
|
form_class = EpisodeForm
|
||||||
|
|
|
@ -16,6 +16,7 @@ __all__ = [
|
||||||
"BasePageDetailView",
|
"BasePageDetailView",
|
||||||
"PageDetailView",
|
"PageDetailView",
|
||||||
"PageListView",
|
"PageListView",
|
||||||
|
"PageUpdateView",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.template.response import TemplateResponse
|
from django.views.generic.base import TemplateView
|
||||||
|
|
||||||
from aircox.models import Program
|
from aircox.models import Program
|
||||||
|
from aircox.views import BaseView
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
class ProfileView(LoginRequiredMixin, BaseView, TemplateView):
|
||||||
def profile(request):
|
template_name = "accounts/profile.html"
|
||||||
programs = []
|
|
||||||
ugroups = request.user.groups.all()
|
def get_context_data(self, **kwargs):
|
||||||
for p in Program.objects.all():
|
groups = self.request.user.groups.all()
|
||||||
if p.editors in ugroups:
|
programs = Program.objects.filter(editors__in=groups)
|
||||||
programs.append(p)
|
kwargs.update({"user": self.request.user, "programs": programs})
|
||||||
context = {"user": request.user, "programs": programs}
|
return super().get_context_data(**kwargs)
|
||||||
return TemplateResponse(request, "accounts/profile.html", context)
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||||
from django.forms import ModelForm, ImageField
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from aircox.forms import ProgramForm
|
||||||
from filer.models.imagemodels import Image
|
from aircox.models import Article, Episode, Page, Program, StaticPage
|
||||||
|
|
||||||
|
|
||||||
from ..models import Article, Episode, Page, Program, StaticPage
|
|
||||||
from .mixins import ParentMixin
|
from .mixins import ParentMixin
|
||||||
from .page import PageDetailView, PageListView, PageUpdateView
|
from .page import PageDetailView, PageListView, PageUpdateView
|
||||||
|
|
||||||
|
@ -56,22 +52,6 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
|
||||||
return super().get_template_names() + ["aircox/program_detail.html"]
|
return super().get_template_names() + ["aircox/program_detail.html"]
|
||||||
|
|
||||||
|
|
||||||
class ProgramForm(ModelForm):
|
|
||||||
content = RichTextField()
|
|
||||||
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
|
||||||
form_class = ProgramForm
|
form_class = ProgramForm
|
||||||
|
|
Loading…
Reference in New Issue
Block a user