Fixed work create and some security issues

This commit is contained in:
Tris Forster 2023-02-20 10:28:38 +11:00
parent 5a201cef85
commit e74043ae67
5 changed files with 60 additions and 26 deletions

View File

@ -9,7 +9,7 @@ class WorkCreateForm(forms.ModelForm, BaseForm):
class Meta:
model = Work
fields = ['name', 'composer', 'edition', 'code', 'running_time', 'notes']
fields = ['name', 'composer', 'edition', 'code', 'orchestration', 'licence', 'running_time', 'notes']
class PlaylistAddForm(forms.Form):
work = forms.ModelChoiceField(queryset=Work.objects.all())

View File

@ -0,0 +1,33 @@
# Generated by Django 3.2.7 on 2023-02-19 23:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('library', '0011_section_page'),
]
operations = [
migrations.RemoveField(
model_name='orchestration',
name='ensemble',
),
migrations.AddField(
model_name='orchestration',
name='collection',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='custom_orchestrations', to='library.collection'),
),
migrations.AlterField(
model_name='work',
name='original_parts',
field=models.JSONField(blank=True, default=dict, help_text='Original printed parts (IMSLP format)'),
),
migrations.AlterField(
model_name='work',
name='running_time',
field=models.DurationField(blank=True, help_text='Running time in mm:ss format', null=True),
),
]

View File

@ -33,7 +33,9 @@ class Orchestration(models.Model):
Stores a list of instrument codes as a single entry (space delimited).
Can be global or ensemble specific
"""
ensemble = models.ForeignKey('interface.Ensemble', on_delete=models.CASCADE, related_name="orchestrations", null=True, blank=True)
# TODO: change ensemble to collection
#ensemble = models.ForeignKey('interface.Ensemble', on_delete=models.CASCADE, related_name="orchestrations", null=True, blank=True)
collection = models.ForeignKey('Collection', on_delete=models.CASCADE, related_name="custom_orchestrations", null=True, blank=True)
name = models.CharField(max_length=100)
instruments = models.TextField()
@ -181,7 +183,7 @@ class Work(models.Model):
max_projects = models.IntegerField(default=1, help_text="How many active projects can this work be attached to")
# Extra info
running_time = models.DurationField(null=True, blank=True, help_text="Running time in seconds")
running_time = models.DurationField(null=True, blank=True, help_text="Running time in mm:ss format")
notes = models.TextField(blank=True)
# Allocation to projects

View File

@ -161,7 +161,7 @@ class WorkListView(CollectionMixin, ListView):
def get_works(self):
collections = CollectionMixin.get_queryset(self)
return Work.objects.filter(collection__in=collections).order_by('name').distinct().select_related('collection')
return Work.objects.filter(collection__in=collections).select_related('collection')
def get_context_data(self, *args, **kwargs):
data = super(WorkListView, self).get_context_data(*args, **kwargs)
@ -180,15 +180,16 @@ class WorkListView(CollectionMixin, ListView):
else:
works = works.filter(Q(name__contains=q) | Q(composer__contains=q) | Q(meta_info__value__contains=q))
return works.order_by('name', 'pk')
return works.order_by('name', 'composer', 'edition', 'pk')
class CollectionWorkListView(WorkListView):
def get_works(self):
works = Work.objects.filter(collection=self.kwargs['collection']).distinct()
works = Work.objects.filter(collection=self.kwargs['collection'])
loan_count = Count('project_items', Q(project_items__checkout__lte=now(), project_items__returned=None))
works = works.annotate(loan_count=loan_count)
if self.request.is_admin:
loan_count = Count('project_items', Q(project_items__checkout__lte=now(), project_items__returned=None))
works = works.annotate(loan_count=loan_count)
return works
def get_context_data(self, *args, **kwargs):
@ -202,6 +203,12 @@ class WorkAddView(CollectionMixin, FormView):
title = "Add a new work"
def get_form(self, form_class=None):
form = super().get_form(form_class)
qs = models.Orchestration.objects.filter(Q(collection=None) | Q(collection=self.collection))
form.fields['orchestration'].queryset = qs.order_by('-collection_id', 'pk')
return form
def form_valid(self, form):
work = form.save(commit=False)
#work.ensemble_id = self.request.ensemble_id
@ -219,19 +226,12 @@ class WorkAddView(CollectionMixin, FormView):
else:
return redirect('work_detail', collection=self.collection.pk, pk=work.pk)
class WorkMixin(object):
def get_queryset(self):
if self.request.is_admin:
return Work.objects.all()
return Work.objects.filter(collection__allowed_ensembles__ensemble=self.request.ensemble_id)
class WorkDetailView(CollectionMixin, WorkMixin, DetailView):
class WorkDetailView(CollectionMixin, DetailView):
pass
class WorkUpdateView(CollectionMixin, WorkMixin, UpdateView):
fields = ['name', 'composer', 'edition', 'code', 'licence', 'max_projects', 'running_time', 'notes']
class WorkUpdateView(CollectionMixin, UpdateView):
#fields = ['name', 'composer', 'edition', 'code', 'orchestration', 'licence', 'max_projects', 'running_time', 'notes']
form_class = forms.WorkCreateForm
template_name = 'interface/default_form.html'
def get_success_url(self):
@ -266,7 +266,7 @@ class WorkAddToProject(ProjectMixin, FormView):
class WorkPartSetView(EnsembleMixin, DetailView):
class WorkPartSetView(CollectionMixin, DetailView):
template_name = "library/work_partset.html"
def post(self, request, *args, **kwargs):

View File

@ -32,8 +32,7 @@ class WorkExportView(EnsembleMixin, WorkMixin, View):
"""
from library.views import WorkMixin
from interface.views import EnsembleMixin
from interface.views import AuthorizedResourceMixin
from rest_framework import routers, serializers, viewsets
@ -168,25 +167,25 @@ class CollectionSerializer(serializers.Serializer):
from rest_framework import generics
class CollectionExportView(generics.RetrieveAPIView):
class CollectionExportView(AuthorizedResourceMixin, generics.RetrieveAPIView):
serializer_class = CollectionSerializer
def get_queryset(self):
return Collection.objects.filter(administrators=self.request.user)
class WorkExportView(generics.RetrieveAPIView):
class WorkExportView(AuthorizedResourceMixin, generics.RetrieveAPIView):
serializer_class = WorkSerializer
def get_queryset(self):
return Work.objects.filter(collection__administrators=self.request.user)
class WorkImportView(generics.CreateAPIView):
class WorkImportView(AuthorizedResourceMixin, generics.CreateAPIView):
serializer_class = WorkSerializer
def perform_create(self, serializer):
serializer.save(collection_id=self.kwargs['pk'])
class CollectionImportView(generics.CreateAPIView):
class CollectionImportView(AuthorizedResourceMixin, generics.CreateAPIView):
serializer_class = CollectionSerializer
def perform_create(self, serializer):