notes
This commit is contained in:
parent
1aababe2ae
commit
722f76767e
|
@ -143,6 +143,9 @@ class Program(Page):
|
|||
def save(self, *kargs, **kwargs):
|
||||
from .sound import Sound
|
||||
|
||||
# FIXME: can be moved here to avoid multiple database hits
|
||||
self.set_group_ownership()
|
||||
|
||||
super().save(*kargs, **kwargs)
|
||||
|
||||
# TODO: move in signals
|
||||
|
@ -158,9 +161,6 @@ class Program(Page):
|
|||
shutil.move(abspath, self.abspath)
|
||||
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
|
||||
|
||||
self.set_group_ownership()
|
||||
super().save(*kargs, **kwargs)
|
||||
|
||||
|
||||
class ProgramChildQuerySet(PageQuerySet):
|
||||
def station(self, station=None, id=None):
|
||||
|
|
|
@ -59,8 +59,12 @@ def do_get_tracks(obj):
|
|||
@register.simple_tag(name="has_perm", takes_context=True)
|
||||
def do_has_perm(context, obj, perm, user=None, simple=False):
|
||||
"""Return True if ``user.has_perm('[APP].[perm]_[MODEL]')``"""
|
||||
# FIXME: is there any case when this method is used without obj?
|
||||
# => here we assume this shouldn't happen: obj has no default value,
|
||||
# If it still required, you should return a boolean value in order
|
||||
# to keep the same signature and contract with the function.
|
||||
if not obj:
|
||||
return
|
||||
return False
|
||||
if user is None:
|
||||
user = context["request"].user
|
||||
if simple:
|
||||
|
@ -104,8 +108,9 @@ def do_player_live_attr(context):
|
|||
@register.simple_tag(name="nav_items", takes_context=True)
|
||||
def do_nav_items(context, menu, **kwargs):
|
||||
"""Render navigation items for the provided menu name."""
|
||||
if not getattr(context["request"], "station"):
|
||||
return []
|
||||
# This should not happen
|
||||
# if not getattr(context["request"], "station"):
|
||||
# return []
|
||||
station, request = context["station"], context["request"]
|
||||
return [(item, item.render(request, **kwargs)) for item in station.navitem_set.filter(menu=menu)]
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
|||
from aircox.models import Program
|
||||
|
||||
|
||||
# FIXME: better to be put in an external file, eventually load only once in tests.conftest
|
||||
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"
|
||||
|
@ -58,6 +59,8 @@ def test_edit_tracklist(user, client, program, episode, tracks):
|
|||
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 = list(chain(*tracklist_details_reversed))
|
||||
# FIXME: for this too. If you wan't it cleaner
|
||||
# also use `.format` instead of `%`.
|
||||
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-0-id": ["%s"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["%s"], "form-0-title": ["%s"],
|
||||
|
@ -70,4 +73,9 @@ def test_edit_tracklist(user, client, program, episode, tracks):
|
|||
)
|
||||
r = client.post(reverse("episode-edit", kwargs={"pk": episode.pk}), json.loads(data), follow=True)
|
||||
assert r.status_code == 200
|
||||
assert [t.id for t in episode.track_set.all().order_by("position")] == list(reversed(tracklist))
|
||||
# FIXME: u can use set and values_list for comparison. It might be possible in this case that `all()` is not
|
||||
# required.
|
||||
# also you can create directly tracklist as a set: tracklist = set(episode.track_set.all().order_by("position"))
|
||||
# => insertion order is preserved in python 3.*
|
||||
assert set(episode.track_set.all().values_list("id", flat=True)) == set(tracklist)
|
||||
# assert [t.id for t in episode.track_set.all().order_by("position")] == list(reversed(tracklist))
|
||||
|
|
|
@ -53,6 +53,7 @@ class PodcastListView(EpisodeListView):
|
|||
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
|
||||
|
||||
|
||||
# FIXME: to move in aircox.forms
|
||||
class EpisodeForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_podcast = FileField(required=False)
|
||||
|
|
|
@ -16,6 +16,8 @@ __all__ = [
|
|||
"BasePageDetailView",
|
||||
"PageDetailView",
|
||||
"PageListView",
|
||||
# FIXME: don't forget to export public members of the module ;)
|
||||
"PageUpdateView",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -4,12 +4,13 @@ from django.template.response import TemplateResponse
|
|||
from aircox.models import Program
|
||||
|
||||
|
||||
# Note: this is always better to use class-based view, even for a simple templated
|
||||
# one. There is aircox.views.View class that provides the current station and other utils.
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
programs = []
|
||||
ugroups = request.user.groups.all()
|
||||
for p in Program.objects.all():
|
||||
if p.editors in ugroups:
|
||||
programs.append(p)
|
||||
groups = request.user.groups.all()
|
||||
programs = Program.objects.filter(editors__in=groups)
|
||||
context = {"user": request.user, "programs": programs}
|
||||
return TemplateResponse(request, "accounts/profile.html", context)
|
||||
|
|
|
@ -12,7 +12,7 @@ from ..models import Article, Episode, Page, Program, StaticPage
|
|||
from .mixins import ParentMixin
|
||||
from .page import PageDetailView, PageListView, PageUpdateView
|
||||
|
||||
__all__ = ["ProgramPageDetailView", "ProgramDetailView", "ProgramPageListView"]
|
||||
__all__ = ["ProgramPageDetailView", "ProgramDetailView", "ProgramPageListView", "ProgramUpdateView"]
|
||||
|
||||
|
||||
class BaseProgramMixin:
|
||||
|
@ -56,6 +56,7 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
|
|||
return super().get_template_names() + ["aircox/program_detail.html"]
|
||||
|
||||
|
||||
# FIXME: forms should be put in aircox.forms
|
||||
class ProgramForm(ModelForm):
|
||||
content = RichTextField()
|
||||
new_cover = ImageField(required=False)
|
||||
|
@ -76,9 +77,7 @@ class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
|
|||
model = Program
|
||||
form_class = ProgramForm
|
||||
|
||||
def get_sidebar_queryset(self):
|
||||
return super().get_sidebar_queryset().filter(parent=self.program)
|
||||
|
||||
# FIXME: ???
|
||||
def test_func(self):
|
||||
program = self.get_object()
|
||||
return self.request.user.has_perm("aircox.%s" % program.change_permission_codename)
|
||||
|
|
5
dev-1.0-121-notes.md
Normal file
5
dev-1.0-121-notes.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
- nav_items: this method should be called only if there is a station in the context.
|
||||
- idea behind the station is that a station is always defined, except in one case: just right the platform is installed. Otherwise the idea is that user can eventually select the station through a dropbox in the nav menu (happened in last versions of aircox in the admin, should still be there).
|
||||
- don't forget to add your exported module member name to __all__ ;)
|
||||
- it is better to put forms inside aircox.forms submodule (as aircox.forms.program subfiles, etc. if the file is to big + reexport in aircox.forms.__init__)
|
||||
- you can eventually regroup urls under "/admin" or sth like this, in order to avoid mixing public and backoffice urls.
|
Loading…
Reference in New Issue
Block a user