Skip to content
Snippets Groups Projects
Commit a5239bfb authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

fix: don’t enforce valid instance references in collection filters

If a collection is filtered by an invalid id (meaning the model the
query argument points to with that specific id does not exist), we no
longer return an error. Instead the filter is applied without a lookup.

Fixes #104
parent 88595646
No related branches found
No related tags found
1 merge request!21Add API documentation
Pipeline #1770 passed
...@@ -3,7 +3,7 @@ import datetime ...@@ -3,7 +3,7 @@ import datetime
from django_filters import rest_framework as filters from django_filters import rest_framework as filters
from django_filters import widgets from django_filters import widgets
from django.contrib.auth.models import User from django import forms
from django.db.models import Q, QuerySet from django.db.models import Q, QuerySet
from django.utils import timezone from django.utils import timezone
from program import models from program import models
...@@ -19,7 +19,7 @@ class StaticFilterHelpTextMixin: ...@@ -19,7 +19,7 @@ class StaticFilterHelpTextMixin:
return _filter return _filter
class ModelMultipleChoiceFilter(filters.ModelMultipleChoiceFilter): class IntegerInFilter(filters.BaseInFilter):
class QueryArrayWidget(widgets.QueryArrayWidget): class QueryArrayWidget(widgets.QueryArrayWidget):
# see: https://github.com/carltongibson/django-filter/issues/1047 # see: https://github.com/carltongibson/django-filter/issues/1047
def value_from_datadict(self, data, files, name): def value_from_datadict(self, data, files, name):
...@@ -31,17 +31,12 @@ class ModelMultipleChoiceFilter(filters.ModelMultipleChoiceFilter): ...@@ -31,17 +31,12 @@ class ModelMultipleChoiceFilter(filters.ModelMultipleChoiceFilter):
new_data[key] = data.getlist(key) new_data[key] = data.getlist(key)
return super().value_from_datadict(new_data, files, name) return super().value_from_datadict(new_data, files, name)
field_class = forms.IntegerField
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
kwargs.setdefault("widget", self.QueryArrayWidget()) kwargs.setdefault("widget", self.QueryArrayWidget())
kwargs["lookup_expr"] = "in"
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def get_filter_predicate(self, v):
# There is something wrong with using ModelMultipleChoiceFilter
# along the CSVWidget that causes lookups to fail.
# May be related to: https://github.com/carltongibson/django-filter/issues/1103
return super().get_filter_predicate([v.pk])
class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
active = filters.BooleanFilter( active = filters.BooleanFilter(
...@@ -52,34 +47,31 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): ...@@ -52,34 +47,31 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
"or past or upcoming shows if false." "or past or upcoming shows if false."
), ),
) )
host = ModelMultipleChoiceFilter( host = IntegerInFilter(
queryset=models.Host.objects.all(),
field_name="hosts", field_name="hosts",
help_text="Return only shows assigned to the given host(s).", help_text="Return only shows assigned to the given host(s).",
) )
# TODO: replace `musicfocus` with `music_focus` when dashboard is updated # TODO: replace `musicfocus` with `music_focus` when dashboard is updated
musicfocus = ModelMultipleChoiceFilter( musicfocus = IntegerInFilter(
queryset=models.MusicFocus.objects.all(),
field_name="music_focus", field_name="music_focus",
help_text="Return only shows with given music focus(es).", help_text="Return only shows with given music focus(es).",
) )
owner = ModelMultipleChoiceFilter( owner = IntegerInFilter(
queryset=User.objects.all(),
field_name="owners", field_name="owners",
help_text="Return only shows that belong to the given owner(s).", help_text="Return only shows that belong to the given owner(s).",
) )
category = ModelMultipleChoiceFilter( category = IntegerInFilter(
queryset=models.Category.objects.all(),
help_text="Return only shows of the given category or categories.", help_text="Return only shows of the given category or categories.",
) )
language = ModelMultipleChoiceFilter( language = IntegerInFilter(
queryset=models.Language.objects.all(),
help_text="Return only shows of the given language(s).", help_text="Return only shows of the given language(s).",
) )
topic = ModelMultipleChoiceFilter( topic = IntegerInFilter(
queryset=models.Topic.objects.all(),
help_text="Return only shows of the given topic(s).", help_text="Return only shows of the given topic(s).",
) )
type = IntegerInFilter(
help_text="Return only shows of a given type.",
)
public = filters.BooleanFilter( public = filters.BooleanFilter(
field_name="is_public", field_name="is_public",
help_text="Return only shows that are public/non-public.", help_text="Return only shows that are public/non-public.",
...@@ -113,9 +105,6 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): ...@@ -113,9 +105,6 @@ class ShowFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
class Meta: class Meta:
model = models.Show model = models.Show
help_texts = {
"type": "Return only shows of a given type.",
}
fields = [ fields = [
"active", "active",
"category", "category",
...@@ -224,14 +213,12 @@ class TimeSlotFilterSet(filters.FilterSet): ...@@ -224,14 +213,12 @@ class TimeSlotFilterSet(filters.FilterSet):
class NoteFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): class NoteFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
ids = ModelMultipleChoiceFilter( ids = IntegerInFilter(
field_name="id", field_name="id",
queryset=models.Note.objects.all(),
help_text="Return only notes matching the specified id(s).", help_text="Return only notes matching the specified id(s).",
) )
owner = ModelMultipleChoiceFilter( owner = IntegerInFilter(
field_name="show__owners", field_name="show__owners",
queryset=models.User.objects.all(),
help_text="Return only notes by show the specified owner(s): all notes the user may edit.", help_text="Return only notes by show the specified owner(s): all notes the user may edit.",
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment