Filter model and api
This commit is contained in:
parent
7b2999fb81
commit
cfe7962f14
@ -4,7 +4,7 @@ import logging
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.home.models import SubChannel, Subscription, SavedGuilds
|
||||
from apps.home.models import SubChannel, Filter, Subscription, SavedGuilds
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -118,6 +118,16 @@ class SubChannelSerializer(DynamicModelSerializer):
|
||||
fields = ("id", "channel_id", "subscription")
|
||||
|
||||
|
||||
class FilterSerializer(DynamicModelSerializer):
|
||||
"""
|
||||
Serializer for the Filter Model.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Filter
|
||||
fields = ("id", "name", "keywords", "regex", "guild_id")
|
||||
|
||||
|
||||
class SubscriptionSerializer(DynamicModelSerializer):
|
||||
"""
|
||||
Serializer for the Subscription Model.
|
||||
|
@ -6,6 +6,8 @@ from rest_framework.authtoken.views import obtain_auth_token
|
||||
from .views import (
|
||||
SubChannel_ListView,
|
||||
SubChannel_DetailView,
|
||||
Filter_ListView,
|
||||
Filter_DetailView,
|
||||
Subscription_ListView,
|
||||
Subscription_DetailView,
|
||||
Subscription_SubChannelView,
|
||||
@ -13,7 +15,6 @@ from .views import (
|
||||
SavedGuild_DetailView
|
||||
)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
|
||||
path("api-token-auth/", obtain_auth_token),
|
||||
@ -23,6 +24,11 @@ urlpatterns = [
|
||||
path("<str:pk>/", SubChannel_DetailView.as_view(), name="subchannel-detail")
|
||||
])),
|
||||
|
||||
path("filter/", include([
|
||||
path("", Filter_ListView.as_view(), name="filter"),
|
||||
path("<str:pk>/", Filter_DetailView.as_view(), name="filter-detail")
|
||||
])),
|
||||
|
||||
path("subscription/", include([
|
||||
path("", Subscription_ListView.as_view(), name="subscription"),
|
||||
path("<str:pk>/", include([
|
||||
@ -35,4 +41,4 @@ urlpatterns = [
|
||||
path("", SavedGuild_ListView.as_view(), name="saved-guilds"),
|
||||
path("<int:pk>/", SavedGuild_DetailView.as_view(), name="saved-guilds-detail")
|
||||
])),
|
||||
]
|
||||
]
|
||||
|
@ -11,9 +11,10 @@ from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
|
||||
from rest_framework.parsers import MultiPartParser, FormParser
|
||||
|
||||
from apps.home.models import SubChannel, Subscription, SavedGuilds
|
||||
from apps.home.models import SubChannel, Filter, Subscription, SavedGuilds
|
||||
from .serializers import (
|
||||
SubChannelSerializer,
|
||||
FilterSerializer,
|
||||
SubscriptionSerializer,
|
||||
SavedGuildSerializer
|
||||
)
|
||||
@ -83,6 +84,76 @@ class SubChannel_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
||||
queryset = SubChannel.objects.all().order_by("id")
|
||||
|
||||
|
||||
# =================================================================================================
|
||||
# Filter Views
|
||||
|
||||
class Filter_ListView(generics.ListCreateAPIView):
|
||||
"""
|
||||
View to provide a list of Filter model instances.
|
||||
Can also be used to create a new instance.
|
||||
|
||||
Supports: GET, POST
|
||||
"""
|
||||
|
||||
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
pagination_class = DefaultPagination
|
||||
serializer_class = FilterSerializer
|
||||
|
||||
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
||||
filterset_fields = ["id", "name", "keywords", "regex", "guild_id"]
|
||||
search_fields = ["name", "keywords", "regex"]
|
||||
|
||||
def get_queryset(self):
|
||||
saved_guild_ids = SavedGuilds.objects \
|
||||
.filter(added_by=self.request.user.id) \
|
||||
.values("guild_id")
|
||||
|
||||
return Filter.objects \
|
||||
.filter(guild_id__in=Subquery(saved_guild_ids)) \
|
||||
.order_by("id")
|
||||
|
||||
def post(self, request):
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
try:
|
||||
self.perform_create(serializer)
|
||||
except IntegrityError as err:
|
||||
return Response(
|
||||
{"detail": str(err)},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
exception=True
|
||||
)
|
||||
|
||||
headers = self.get_success_headers(serializer.data)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
||||
|
||||
|
||||
class Filter_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
View to provide details on a particular Filter model instances.
|
||||
|
||||
Supports: GET, PUT, PATCH, DELETE
|
||||
"""
|
||||
|
||||
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
parser_classes = [MultiPartParser, FormParser]
|
||||
|
||||
serializer_class = FilterSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
saved_guild_ids = SavedGuilds.objects \
|
||||
.filter(added_by=self.request.user.id) \
|
||||
.values("guild_id")
|
||||
|
||||
return Filter.objects \
|
||||
.filter(guild_id__in=Subquery(saved_guild_ids)) \
|
||||
.order_by("id")
|
||||
|
||||
|
||||
# =================================================================================================
|
||||
# Subscription Views
|
||||
|
||||
|
@ -5,10 +5,8 @@ from uuid import uuid4
|
||||
from pathlib import Path
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
from django.dispatch import receiver
|
||||
from django.db.utils import IntegrityError
|
||||
from django.db.models.signals import pre_save
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.files.storage import FileSystemStorage
|
||||
from django.utils.deconstruct import deconstructible
|
||||
@ -144,6 +142,57 @@ class SubChannel(models.Model):
|
||||
]
|
||||
|
||||
|
||||
class Filter(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
|
||||
name = models.CharField(
|
||||
max_length=32,
|
||||
null=False,
|
||||
blank=False
|
||||
)
|
||||
|
||||
keywords = models.CharField(
|
||||
maxlength=128,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
|
||||
regex = models.CharField(
|
||||
max_length=128,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
|
||||
# Have to use charfield instead of positiveBigIntegerField due to an Sqlite
|
||||
# issue that rounds down the value
|
||||
# https://github.com/sequelize/sequelize/issues/9335
|
||||
guild_id = models.CharField(
|
||||
max_length=128
|
||||
)
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Metadata for the Filter Model.
|
||||
"""
|
||||
|
||||
verbose_name = "filter"
|
||||
verbose_name_plural = "filters"
|
||||
get_latest_by = "id"
|
||||
constaints = [
|
||||
models.CheckConstraint(
|
||||
check=(
|
||||
(Q(keywords__isnull=False) & Q(regex__isnull=True)) |
|
||||
(Q(keywords__isnull=True) & Q(regex__isnull=False))
|
||||
),
|
||||
name="either keywords or regex null, other not null"
|
||||
),
|
||||
models.UniqueConstraint(
|
||||
fields=["name", "guild_id"],
|
||||
name="unique name & server pair")
|
||||
|
||||
]
|
||||
|
||||
|
||||
class Subscription(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user