-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract out common filter class for parent object filtering
- Loading branch information
1 parent
6ad06ab
commit d3afc51
Showing
14 changed files
with
187 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,7 @@ | |
SUPPRESS_TEST_OUTPUT = True | ||
|
||
AWS_ENDPOINT_URL = None | ||
|
||
INSTALLED_APPS += [ | ||
"api.core.tests.apps.CoreTestsConfig", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from rest_framework import filters | ||
|
||
from django.core.exceptions import ImproperlyConfigured | ||
|
||
|
||
class ParentFilter(filters.BaseFilterBackend): | ||
def filter_queryset(self, request, queryset, view): | ||
parent_id_lookup_field = getattr(view, "parent_id_lookup_field", None) | ||
if not parent_id_lookup_field: | ||
raise ImproperlyConfigured( | ||
f"Cannot use {self.__class__.__name__} on a view which does not have a parent_id_lookup_field attribute" | ||
) | ||
|
||
lookup = { | ||
parent_id_lookup_field: view.kwargs["pk"], | ||
} | ||
return queryset.filter(**lookup) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class CoreTestsConfig(AppConfig): | ||
name = "api.core.tests" | ||
label = "api_core_tests" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Generated by Django 4.2.9 on 2024-02-09 14:48 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="ParentModel", | ||
fields=[ | ||
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
("name", models.CharField(max_length=255)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name="ChildModel", | ||
fields=[ | ||
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), | ||
("name", models.CharField(max_length=255)), | ||
( | ||
"parent", | ||
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="api_core_tests.parentmodel"), | ||
), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from django.db import models | ||
|
||
|
||
class ParentModel(models.Model): | ||
name = models.CharField(max_length=255) | ||
|
||
|
||
class ChildModel(models.Model): | ||
name = models.CharField(max_length=255) | ||
parent = models.ForeignKey(ParentModel, on_delete=models.CASCADE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from rest_framework import serializers | ||
|
||
from api.core.tests.models import ChildModel | ||
|
||
|
||
class ChildModelSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = ChildModel | ||
fields = ( | ||
"id", | ||
"name", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import uuid | ||
|
||
from django.core.exceptions import ImproperlyConfigured | ||
from django.test import ( | ||
override_settings, | ||
SimpleTestCase, | ||
TestCase, | ||
) | ||
from django.urls import reverse | ||
|
||
from api.core.tests.models import ( | ||
ChildModel, | ||
ParentModel, | ||
) | ||
|
||
|
||
@override_settings( | ||
ROOT_URLCONF="api.core.tests.urls", | ||
) | ||
class TestMisconfiguredParentFilter(SimpleTestCase): | ||
def test_misconfigured_parent_filter(self): | ||
url = reverse( | ||
"test-misconfigured-parent-filter", | ||
kwargs={ | ||
"pk": str(uuid.uuid4()), | ||
"child_pk": str(uuid.uuid4()), | ||
}, | ||
) | ||
with self.assertRaises(ImproperlyConfigured): | ||
self.client.get(url) | ||
|
||
|
||
@override_settings( | ||
ROOT_URLCONF="api.core.tests.urls", | ||
) | ||
class TestParentFilter(TestCase): | ||
def test_parent_filter(self): | ||
parent = ParentModel.objects.create(name="parent") | ||
child = ChildModel.objects.create(parent=parent, name="child") | ||
url = reverse( | ||
"test-parent-filter", | ||
kwargs={ | ||
"pk": str(parent.pk), | ||
"child_pk": str(child.pk), | ||
}, | ||
) | ||
response = self.client.get(url) | ||
self.assertEqual(response.status_code, 200) | ||
|
||
def test_parent_other_parent_filter(self): | ||
parent = ParentModel.objects.create(name="parent") | ||
child = ChildModel.objects.create(parent=parent, name="child") | ||
other_parent = ParentModel.objects.create(name="other_parent") | ||
url = reverse( | ||
"test-parent-filter", | ||
kwargs={ | ||
"pk": str(other_parent.pk), | ||
"child_pk": str(child.pk), | ||
}, | ||
) | ||
response = self.client.get(url) | ||
self.assertEqual(response.status_code, 404) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from django.urls import path | ||
|
||
from .views import ( | ||
MisconfiguredParentFilterView, | ||
ParentFilterView, | ||
) | ||
|
||
urlpatterns = [ | ||
path( | ||
"misconfigured-parent/<str:pk>/child/<str:child_pk>/", | ||
MisconfiguredParentFilterView.as_view(), | ||
name="test-misconfigured-parent-filter", | ||
), | ||
path( | ||
"parent/<str:pk>/child/<str:child_pk>/", | ||
ParentFilterView.as_view(), | ||
name="test-parent-filter", | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from rest_framework.generics import RetrieveAPIView | ||
|
||
from api.core.filters import ParentFilter | ||
from api.core.tests.models import ChildModel | ||
from api.core.tests.serializers import ChildModelSerializer | ||
|
||
|
||
class MisconfiguredParentFilterView(RetrieveAPIView): | ||
filter_backends = (ParentFilter,) | ||
queryset = ChildModel.objects.all() | ||
|
||
|
||
class ParentFilterView(RetrieveAPIView): | ||
filter_backends = (ParentFilter,) | ||
parent_id_lookup_field = "parent_id" | ||
queryset = ChildModel.objects.all() | ||
serializer_class = ChildModelSerializer |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters