Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPROVEMENT] Use django-filters for api filtering #126

Merged
merged 1 commit into from
Apr 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions docker/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ certifi==2018.10.15
chardet==3.0.4
defusedxml==0.5.0 ; python_version >= '3.0'
dj-database-url==0.5.0
django-filter==2.1.0
django==2.1.2
djangorestframework==3.9.0
envdir==1.0.1
gunicorn==19.9.0
idna==2.7
Expand All @@ -20,12 +22,12 @@ python3-openid==3.1.0 ; python_version >= '3.0'
pytz==2018.7
pyyaml==3.13
raven==6.9.0
redis==2.10.6
redis==3.0.1
requests-oauthlib==1.0.0
requests==2.20.0
requests==2.20.1
six==1.11.0
social-auth-app-django==3.1.0
social-auth-core==2.0.0
urllib3==1.24.1
vine==1.1.4
whitenoise==4.1
whitenoise==4.1.2
28 changes: 28 additions & 0 deletions promgen/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import django_filters


class ShardFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr="contains")


class ServiceFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr="contains")
shard = django_filters.CharFilter(field_name="shard__name", lookup_expr="contains")


class ProjectFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr="contains")
service = django_filters.CharFilter(
field_name="service__name", lookup_expr="contains"
)
shard = django_filters.CharFilter(
field_name="service__shard__name", lookup_expr="contains"
)


class RuleFilter(django_filters.rest_framework.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr="contains")
parent = django_filters.CharFilter(
field_name="parent__name", lookup_expr="contains"
)
enabled = django_filters.BooleanFilter(field_name="enabled")
5 changes: 4 additions & 1 deletion promgen/rest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from django.conf import settings
from django.http import HttpResponse
from promgen import models, prometheus, serializers
from promgen import filters, models, prometheus, serializers
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response


class ShardViewSet(viewsets.ModelViewSet):
queryset = models.Shard.objects.all()
filterset_class = filters.ShardFilter
serializer_class = serializers.ShardSerializer
lookup_field = 'name'

Expand Down Expand Up @@ -35,6 +36,7 @@ def format(self, rules=None, name='promgen'):

class ServiceViewSet(SharedViewSet, viewsets.ModelViewSet):
queryset = models.Service.objects.prefetch_related('shard')
filterset_class = filters.ServiceFilter
serializer_class = serializers.ServiceSerializer
lookup_value_regex = '[^/]+'
lookup_field = 'name'
Expand Down Expand Up @@ -71,6 +73,7 @@ class ProjectViewSet(SharedViewSet, viewsets.ModelViewSet):
queryset = models.Project.objects.prefetch_related(
'service', 'service__shard', 'farm'
)
filterset_class = filters.ProjectFilter
serializer_class = serializers.ProjectSerializer
lookup_value_regex = '[^/]+'
lookup_field = 'name'
Expand Down
52 changes: 16 additions & 36 deletions promgen/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
from rest_framework import serializers


class ShardSerializer(serializers.ModelSerializer):
_html = serializers.SerializerMethodField()
_services = serializers.SerializerMethodField()
class WebLinkField(serializers.Field):
def get_attribute(self, instance):
return instance

def to_representation(self, obj):
return shortcuts.resolve_domain(obj.get_absolute_url())

def get__html(self, obj):
return shortcuts.resolve_domain('shard-detail', obj.id)

def get__services(self, obj):
return shortcuts.resolve_domain('api:shard-services', obj.name)
class ShardSerializer(serializers.ModelSerializer):
html = WebLinkField()

class Meta:
model = models.Shard
Expand All @@ -19,20 +20,9 @@ class Meta:


class ServiceSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')

_shard = serializers.SerializerMethodField()
_projects = serializers.SerializerMethodField()
_html = serializers.SerializerMethodField()

def get__html(self, obj):
return shortcuts.resolve_domain('service-detail', obj.id)

def get__shard(self, obj):
return shortcuts.resolve_domain('api:shard-detail', obj.shard.name)

def get__projects(self, obj):
return shortcuts.resolve_domain('api:service-projects', obj.name)
owner = serializers.ReadOnlyField(source="owner.username")
shard = serializers.ReadOnlyField(source="shard.name")
html = WebLinkField()

class Meta:
model = models.Service
Expand All @@ -41,25 +31,15 @@ class Meta:


class ProjectSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')

_html = serializers.SerializerMethodField()
_service = serializers.SerializerMethodField()
_shard = serializers.SerializerMethodField()

def get__html(self, obj):
return shortcuts.resolve_domain('project-detail', obj.id)

def get__service(self, obj):
return shortcuts.resolve_domain('api:service-detail', obj.service.name)

def get__shard(self, obj):
return shortcuts.resolve_domain('api:shard-detail', obj.service.shard.name)
owner = serializers.ReadOnlyField(source="owner.username")
service = serializers.ReadOnlyField(source="service.name")
shard = serializers.ReadOnlyField(source="service.shard.name")
html = WebLinkField()

class Meta:
model = models.Project
exclude = ('id', 'service', 'farm')
lookup_field = 'name'
exclude = ("id", "farm")


class SenderSerializer(serializers.ModelSerializer):
Expand Down
4 changes: 4 additions & 0 deletions promgen/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
'promgen',
'rest_framework',
'rest_framework.authtoken',
'django_filters',
]

# We explicitly include debug_toolbar and whitenoise here, but selectively
Expand Down Expand Up @@ -206,6 +207,9 @@
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
)
}

Expand Down
4 changes: 2 additions & 2 deletions promgen/templates/rest_framework/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
<link rel="stylesheet" href="{% static "/css/bootstrap.min.css" %}">
<link rel="stylesheet" href="{% static "/css/bootstrap-theme.min.css" %}">
<link rel="stylesheet" href="{% static "/css/bootstrap-switch.min.css" %}">
<!-- <link rel="stylesheet" href="{% static "/css/promgen.css" %}"> -->
<link rel="stylesheet" href="{% static "/css/promgen.css" %}">
<link rel="icon" href="{% static "/images/promgen_logo_color.png" %}">
{% endblock %}

{% block script %}
Expand All @@ -32,4 +33,3 @@
});
</script>
{% endblock %}

3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@
'atomicwrites',
'celery[redis]==4.1.1',
'dj-database-url',
'djangorestframework==3.9.0',
'django-filter',
'Django==2.1.2',
'djangorestframework==3.9.0',
'envdir',
'prometheus-client',
'python-dateutil',
Expand Down