Merge branch 'feature-API-filtering' into 'develop'
Feature api filtering See merge request vtmk/web2.0!131
This commit is contained in:
+2
-1
@@ -35,4 +35,5 @@ pyexcel==0.5.8
|
|||||||
pyexcel-xlsx==0.5.5
|
pyexcel-xlsx==0.5.5
|
||||||
django-import-export==0.7.0
|
django-import-export==0.7.0
|
||||||
openpyxl==2.4.11
|
openpyxl==2.4.11
|
||||||
django-app-namespace-template-loader==0.4.1
|
django-app-namespace-template-loader==0.4.1
|
||||||
|
django-filter==2.0.0
|
||||||
@@ -103,6 +103,7 @@ INSTALLED_APPS = [
|
|||||||
'auditlog',
|
'auditlog',
|
||||||
'phonenumber_field',
|
'phonenumber_field',
|
||||||
'import_export',
|
'import_export',
|
||||||
|
'django_filters',
|
||||||
]
|
]
|
||||||
|
|
||||||
IMPORT_EXPORT_USE_TRANSACTIONS = True
|
IMPORT_EXPORT_USE_TRANSACTIONS = True
|
||||||
@@ -232,6 +233,11 @@ REST_FRAMEWORK = {
|
|||||||
'burst': '60/min',
|
'burst': '60/min',
|
||||||
'sustained': '1000/day'
|
'sustained': '1000/day'
|
||||||
},
|
},
|
||||||
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||||
|
'PAGE_SIZE': 10,
|
||||||
|
'DEFAULT_FILTER_BACKENDS': (
|
||||||
|
'django_filters.rest_framework.DjangoFilterBackend',
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Email settings (tested working with gmail)
|
# Email settings (tested working with gmail)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.0.7 on 2018-11-18 15:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('webapp', '0049_auto_20181118_1344'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='signupform',
|
||||||
|
name='visible',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -93,6 +93,7 @@ class SignupForm(models.Model):
|
|||||||
end = models.DateTimeField(default=timezone.now)
|
end = models.DateTimeField(default=timezone.now)
|
||||||
# question = JSONField()
|
# question = JSONField()
|
||||||
questions = models.CharField(max_length=255)
|
questions = models.CharField(max_length=255)
|
||||||
|
visible = models.BooleanField(default=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Signup form')
|
verbose_name = _('Signup form')
|
||||||
|
|||||||
+17
-6
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
from rest_framework.test import force_authenticate
|
||||||
from webapp.models import Tag, Feed
|
from webapp.models import Tag, Feed
|
||||||
from webapp.serializers import TagSerializer, FeedSerializer
|
from webapp.serializers import TagSerializer, FeedSerializer
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ class TagsTestCase(APITestCase):
|
|||||||
self.assertTrue(status.is_success(response.status_code))
|
self.assertTrue(status.is_success(response.status_code))
|
||||||
|
|
||||||
# We dont care about icon, so response is sliced
|
# We dont care about icon, so response is sliced
|
||||||
sliced_response = OrderedDict(islice(response.data[0].items(), 3))
|
sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3))
|
||||||
tag1 = Tag.objects.get(slug="Party")
|
tag1 = Tag.objects.get(slug="Party")
|
||||||
self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'})
|
self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'})
|
||||||
|
|
||||||
@@ -39,12 +41,12 @@ class TagsTestCase(APITestCase):
|
|||||||
|
|
||||||
# We dont care about icon, so response is sliced
|
# We dont care about icon, so response is sliced
|
||||||
tag1 = Tag.objects.get(slug="Party")
|
tag1 = Tag.objects.get(slug="Party")
|
||||||
sliced_response = OrderedDict(islice(response.data[0].items(), 3))
|
sliced_response = OrderedDict(islice(response.data['results'][0].items(), 3))
|
||||||
self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'})
|
self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'})
|
||||||
sliced_response = OrderedDict(islice(response.data[1].items(), 3))
|
sliced_response = OrderedDict(islice(response.data['results'][1].items(), 3))
|
||||||
tag2 = Tag.objects.get(slug="Freshmen")
|
tag2 = Tag.objects.get(slug="Freshmen")
|
||||||
self.assertEqual(sliced_response, {'id': tag2.id, 'slug': 'Freshmen', 'name': 'Fuksit'})
|
self.assertEqual(sliced_response, {'id': tag2.id, 'slug': 'Freshmen', 'name': 'Fuksit'})
|
||||||
sliced_response = OrderedDict(islice(response.data[2].items(), 3))
|
sliced_response = OrderedDict(islice(response.data['results'][2].items(), 3))
|
||||||
tag3 = Tag.objects.get(slug="International")
|
tag3 = Tag.objects.get(slug="International")
|
||||||
self.assertEqual(sliced_response, {'id': tag3.id, 'slug': 'International', 'name': 'Ulkkarit'})
|
self.assertEqual(sliced_response, {'id': tag3.id, 'slug': 'International', 'name': 'Ulkkarit'})
|
||||||
|
|
||||||
@@ -76,6 +78,9 @@ class FeedTestCase(APITestCase):
|
|||||||
self.assertEqual(Feed.objects.count(), 1)
|
self.assertEqual(Feed.objects.count(), 1)
|
||||||
self.assertEqual(Feed.objects.all()[0].tags.count(), 2)
|
self.assertEqual(Feed.objects.all()[0].tags.count(), 2)
|
||||||
|
|
||||||
|
username, password = 'test_admin', 'password123'
|
||||||
|
self.authClient = User.objects.create_superuser(username, 'myemail@test.com', password)
|
||||||
|
|
||||||
def test_get_feed(self):
|
def test_get_feed(self):
|
||||||
response = self.client.get('/api/feed/', format='json')
|
response = self.client.get('/api/feed/', format='json')
|
||||||
self.assertTrue(status.is_success(response.status_code))
|
self.assertTrue(status.is_success(response.status_code))
|
||||||
@@ -83,7 +88,7 @@ class FeedTestCase(APITestCase):
|
|||||||
feeds = Feed.objects.all()
|
feeds = Feed.objects.all()
|
||||||
serializer = FeedSerializer(feeds, many=True)
|
serializer = FeedSerializer(feeds, many=True)
|
||||||
|
|
||||||
self.assertEqual(response.data, serializer.data)
|
self.assertEqual(response.data['results'], serializer.data)
|
||||||
|
|
||||||
def test_post_feed(self):
|
def test_post_feed(self):
|
||||||
Tag.objects.create(slug="test1", name="testsds")
|
Tag.objects.create(slug="test1", name="testsds")
|
||||||
@@ -92,9 +97,15 @@ class FeedTestCase(APITestCase):
|
|||||||
tag2_id = Tag.objects.get(slug="test2").id
|
tag2_id = Tag.objects.get(slug="test2").id
|
||||||
|
|
||||||
data = {'tags': [tag1_id, tag2_id], 'title': 'testtitle', 'visible': 'True', 'description': 'liirumlaarum', 'content': 'lorem ipsum'}
|
data = {'tags': [tag1_id, tag2_id], 'title': 'testtitle', 'visible': 'True', 'description': 'liirumlaarum', 'content': 'lorem ipsum'}
|
||||||
|
# Try post without authentication
|
||||||
response = self.client.post('/api/feed/', data, format='multipart')
|
response = self.client.post('/api/feed/', data, format='multipart')
|
||||||
|
self.assertTrue(status.is_client_error(response.status_code))
|
||||||
|
self.assertEqual(Feed.objects.count(), 1)
|
||||||
|
# Authenticate
|
||||||
|
self.client.force_authenticate(user=self.authClient)
|
||||||
|
response = self.client.post('/api/feed/', data, format='multipart')
|
||||||
|
# Return success and check object was created
|
||||||
self.assertTrue(status.is_success(response.status_code))
|
self.assertTrue(status.is_success(response.status_code))
|
||||||
|
|
||||||
self.assertEqual(Feed.objects.count(), 2)
|
self.assertEqual(Feed.objects.count(), 2)
|
||||||
|
|
||||||
created = Feed.objects.get(title="testtitle")
|
created = Feed.objects.get(title="testtitle")
|
||||||
|
|||||||
+37
-3
@@ -13,7 +13,9 @@ from rest_framework import viewsets, routers
|
|||||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.reverse import reverse
|
from rest_framework.reverse import reverse
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
from rest_framework.filters import SearchFilter, OrderingFilter
|
||||||
|
from rest_framework import permissions
|
||||||
# import logging
|
# import logging
|
||||||
# import requests
|
# import requests
|
||||||
from dealer.git import git
|
from dealer.git import git
|
||||||
@@ -24,6 +26,14 @@ from webapp.serializers import *
|
|||||||
from members.views.utils import *
|
from members.views.utils import *
|
||||||
|
|
||||||
|
|
||||||
|
class IsPostOrIsAuthenticated(permissions.BasePermission):
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
if request.method == 'POST':
|
||||||
|
return True
|
||||||
|
return request.user and request.user.is_authenticated
|
||||||
|
|
||||||
|
|
||||||
# -- REST API -- #
|
# -- REST API -- #
|
||||||
class RootView(routers.APIRootView):
|
class RootView(routers.APIRootView):
|
||||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||||
@@ -33,18 +43,36 @@ class EventViewSet(viewsets.ModelViewSet):
|
|||||||
queryset = Event.objects.all()
|
queryset = Event.objects.all()
|
||||||
serializer_class = EventSerializer
|
serializer_class = EventSerializer
|
||||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||||
|
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||||
|
filter_fields = '__all__'
|
||||||
|
search_fields = '__all__'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
|
||||||
|
|
||||||
|
|
||||||
class SignupFormViewSet(viewsets.ModelViewSet):
|
class SignupFormViewSet(viewsets.ModelViewSet):
|
||||||
queryset = SignupForm.objects.all()
|
queryset = SignupForm.objects.all()
|
||||||
serializer_class = SignupFormSerializer
|
serializer_class = SignupFormSerializer
|
||||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||||
|
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||||
|
filter_fields = '__all__'
|
||||||
|
search_fields = '__all__'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return SignupForm.objects.filter(visible=True, end__gt=timezone.now()).order_by('start')
|
||||||
|
|
||||||
|
|
||||||
class SignupViewSet(viewsets.ModelViewSet):
|
class SignupViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Signup.objects.all()
|
queryset = Signup.objects.all()
|
||||||
serializer_class = SignupSerializer
|
serializer_class = SignupSerializer
|
||||||
permission_classes = []
|
permission_classes = [IsPostOrIsAuthenticated]
|
||||||
|
# filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||||
|
# filter_fields = '__all__'
|
||||||
|
# search_fields = '__all__'
|
||||||
|
|
||||||
|
# def get_queryset(self):
|
||||||
|
# return Signup.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
|
||||||
|
|
||||||
|
|
||||||
class SavedQuestionsViewSet(viewsets.ModelViewSet):
|
class SavedQuestionsViewSet(viewsets.ModelViewSet):
|
||||||
@@ -56,7 +84,13 @@ class SavedQuestionsViewSet(viewsets.ModelViewSet):
|
|||||||
class FeedViewSet(viewsets.ModelViewSet):
|
class FeedViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Feed.objects.all()
|
queryset = Feed.objects.all()
|
||||||
serializer_class = FeedSerializer
|
serializer_class = FeedSerializer
|
||||||
permission_classes = []
|
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||||
|
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||||
|
filter_fields = '__all__'
|
||||||
|
search_fields = '__all__'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Feed.objects.filter(visible=True, autohide__gt=timezone.now()).order_by('publish_time')
|
||||||
|
|
||||||
|
|
||||||
class ContactsViewSet(viewsets.ReadOnlyModelViewSet):
|
class ContactsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
|
|||||||
Reference in New Issue
Block a user