diff options
author | 2021-07-23 18:58:35 +0800 | |
---|---|---|
committer | 2021-12-18 18:02:11 +0100 | |
commit | b082de6662e1b57f6831d219b44d95f93ed8a884 (patch) | |
tree | 399e94a76d334a82bbb7b3158c8740b4ab935056 | |
parent | Migrate misc field names and help text changes. (diff) |
Correct Filter-FilterList relationship.
Instead of a many-many relationship, one filterlist has multiple
filters. Nested serialization is read-only by default, so not
all CRUD methods are implemented yet for the FilterList viewset.
-rw-r--r-- | pydis_site/apps/api/migrations/0070_new_filter_schema.py | 11 | ||||
-rw-r--r-- | pydis_site/apps/api/models/bot/filters.py | 6 | ||||
-rw-r--r-- | pydis_site/apps/api/serializers.py | 22 | ||||
-rw-r--r-- | pydis_site/apps/api/tests/test_filters.py | 29 | ||||
-rw-r--r-- | pydis_site/apps/api/viewsets/bot/filters.py | 64 |
5 files changed, 68 insertions, 64 deletions
diff --git a/pydis_site/apps/api/migrations/0070_new_filter_schema.py b/pydis_site/apps/api/migrations/0070_new_filter_schema.py index 8580033a..237ce7d7 100644 --- a/pydis_site/apps/api/migrations/0070_new_filter_schema.py +++ b/pydis_site/apps/api/migrations/0070_new_filter_schema.py @@ -54,17 +54,14 @@ def forward(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None: list_type=1 if type_ == "ALLOW" else 0 ) - new_objects = [] for object_ in objects: new_object = filter_.objects.create( content=object_.content, + filter_list = list_, description=object_.comment or "<no description provided>", additional_field=None, override=None ) new_object.save() - new_objects.append(new_object) - - list_.filters.add(*new_objects) class Migration(migrations.Migration): @@ -143,7 +140,6 @@ class Migration(migrations.Migration): ('name', models.CharField(help_text='The unique name of this list.', max_length=50)), ('list_type', models.IntegerField(choices=[], help_text='Whenever this list is an allowlist or denylist')), ('default_settings', models.ForeignKey(help_text='Default parameters of this list.', on_delete=django.db.models.deletion.CASCADE, to='api.FilterSettings')), - ('filters', models.ManyToManyField(help_text='The content of this list.', to='api.Filter', default=[])), ], ), migrations.AddField( @@ -151,6 +147,11 @@ class Migration(migrations.Migration): name='override', field=models.ForeignKey(help_text='Override the default settings.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='api.FilterOverride'), ), + migrations.AddField( + model_name='filter', + name='filter_list', + field=models.ForeignKey(help_text='The filter list containing this filter.', on_delete=django.db.models.deletion.CASCADE, related_name='filters', to='api.FilterList'), + ), migrations.AddConstraint( model_name='filterlist', constraint=models.UniqueConstraint(fields=('name', 'list_type'), name='unique_name_type'), diff --git a/pydis_site/apps/api/models/bot/filters.py b/pydis_site/apps/api/models/bot/filters.py index b5c80bda..99d6d5e4 100644 --- a/pydis_site/apps/api/models/bot/filters.py +++ b/pydis_site/apps/api/models/bot/filters.py @@ -48,8 +48,6 @@ class FilterList(models.Model): choices=FilterListType.choices, help_text="Whether this list is an allowlist or denylist" ) - - filters = models.ManyToManyField("Filter", help_text="The content of this list.", default=[]) default_settings = models.ForeignKey( "FilterSettings", models.CASCADE, @@ -152,6 +150,10 @@ class Filter(models.Model): content = models.CharField(max_length=100, help_text="The definition of this filter.") description = models.CharField(max_length=200, help_text="Why this filter has been added.") additional_field = models.BooleanField(null=True, help_text="Implementation specific field.") + filter_list = models.ForeignKey( + FilterList, models.CASCADE, related_name="filters", + help_text="The filter list containing this filter." + ) override = models.ForeignKey( "FilterOverride", models.SET_NULL, diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index 584d1f22..afcf4d55 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -117,9 +117,21 @@ class DocumentationLinkSerializer(ModelSerializer): fields = ('package', 'base_url', 'inventory_url') +class FilterSerializer(ModelSerializer): + """A class providing (de-)serialization of `Filter` instances.""" + + class Meta: + """Metadata defined for the Django REST Framework.""" + + model = Filter + fields = ('id', 'content', 'description', 'additional_field', 'filter_list', 'override') + + class FilterListSerializer(ModelSerializer): """A class providing (de-)serialization of `FilterList` instances.""" + filters = FilterSerializer(many=True, read_only=True) + class Meta: """Metadata defined for the Django REST Framework.""" @@ -185,16 +197,6 @@ class FilterChannelRangeSerializer(ModelSerializer): ) -class FilterSerializer(ModelSerializer): - """A class providing (de-)serialization of `Filter` instances.""" - - class Meta: - """Metadata defined for the Django REST Framework.""" - - model = Filter - fields = ('id', 'content', 'description', 'additional_field', 'override') - - class FilterOverrideSerializer(ModelSerializer): """A class providing (de-)serialization of `FilterOverride` instances.""" diff --git a/pydis_site/apps/api/tests/test_filters.py b/pydis_site/apps/api/tests/test_filters.py index 2df671e0..f694053d 100644 --- a/pydis_site/apps/api/tests/test_filters.py +++ b/pydis_site/apps/api/tests/test_filters.py @@ -32,7 +32,7 @@ FK_FIELDS: Dict[Type[Model], Tuple[str]] = { FilterSettings: ("default_action", "default_range"), FilterAction: (), ChannelRange: (), - Filter: (), + Filter: ("filter_list",), FilterOverride: ("filter_action", "filter_range") } @@ -122,7 +122,32 @@ def get_test_sequences() -> Dict[str, TestSequence]: "content": "bad word", "description": "This is a really bad word.", "additional_field": None, - "override": None + "override": None, + "filter_list": FilterList( + name="testname", + list_type=0, + default_settings=FilterSettings( + ping_type=[], + filter_dm=False, + dm_ping_type=[], + delete_messages=False, + bypass_roles=[], + enabled=False, + default_action=FilterAction( + dm_content=None, + infraction_type=None, + infraction_reason="", + infraction_duration=None + ), + default_range=ChannelRange( + disallowed_channels=[], + disallowed_categories=[], + allowed_channels=[], + allowed_categories=[], + default=False + ) + ) + ) } ), "filter_override": TestSequence( diff --git a/pydis_site/apps/api/viewsets/bot/filters.py b/pydis_site/apps/api/viewsets/bot/filters.py index 9553fcac..1b893f8c 100644 --- a/pydis_site/apps/api/viewsets/bot/filters.py +++ b/pydis_site/apps/api/viewsets/bot/filters.py @@ -20,7 +20,7 @@ from pydis_site.apps.api.serializers import ( # noqa: I101 - Preserving the fil class FilterListViewSet(ModelViewSet): """ - View providing CRUD operations on lists of items allowed or denied by our bot. + View providing GET/DELETE on lists of items allowed or denied by our bot. ## Routes ### GET /bot/filter/filter_lists @@ -33,8 +33,14 @@ class FilterListViewSet(ModelViewSet): ... "name": "guild_invite", ... "list_type": 1, ... "filters": [ - ... 1, - ... 2, + ... { + ... "id": 1, + ... "content": "267624335836053506", + ... "description": "Python Discord", + ... "additional_field": None, + ... "override": 1, + ... "filter_list": 1 + ... }, ... ... ... ], ... "default_settings": 1 @@ -55,8 +61,14 @@ class FilterListViewSet(ModelViewSet): ... "name": "guild_invite", ... "list_type": 1, ... "filters": [ - ... 1, - ... 2, + ... { + ... "id": 1, + ... "content": "267624335836053506", + ... "description": "Python Discord", + ... "additional_field": None, + ... "override": 1, + ... "filter_list": 1 + ... }, ... ... ... ], ... "default_settings": 1 @@ -66,45 +78,6 @@ class FilterListViewSet(ModelViewSet): - 200: returned on success - 404: returned if the id was not found. - ### POST /bot/filter/filter_lists - Adds a single FilterList item to the database. - - #### Request body - >>> { - ... "name": "guild_invite", - ... "list_type": 1, - ... "filters": [ - ... 1, - ... 2, - ... ... - ... ], - ... "default_settings": 1 - ... } - - #### Status codes - - 201: returned on success - - 400: if one of the given fields is invalid - - ### PATCH /bot/filter/filter_lists/<id:int> - Updates a specific FilterList item from the database. - - #### Response format - >>> { - ... "id": 1, - ... "name": "guild_invite", - ... "list_type": 1, - ... "filters": [ - ... 1, - ... 2, - ... ... - ... ], - ... "default_settings": 1 - ... } - - #### Status codes - - 200: returned on success - - 400: if one of the given fields is invalid - ### DELETE /bot/filter/filter_lists/<id:int> Deletes the FilterList item with the given `id`. @@ -437,7 +410,8 @@ class FilterViewSet(ModelViewSet): ... "content": "267624335836053506", ... "description": "Python Discord", ... "additional_field": None, - ... "override": 1 + ... "override": 1, + ... "filter_list": 1 ... }, ... ... ... ] |