-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
API endpoints and dynamic responses (#9)
* add api endpoints * enable basic auth * change event to Observation * lint and set tests
- Loading branch information
Showing
34 changed files
with
498 additions
and
311 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
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 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 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 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
File renamed without changes.
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 @@ | ||
import factory | ||
from factory import faker | ||
|
||
from ..models import User | ||
|
||
|
||
class UserFactory(factory.django.DjangoModelFactory): | ||
email = faker.Faker("email") | ||
password = factory.PostGenerationMethodCall("set_password", "password") | ||
is_active = True | ||
|
||
class Meta: | ||
model = User | ||
|
||
|
||
class SuperUserFactory(UserFactory): | ||
is_superuser = True |
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,16 @@ | ||
from django.test import TestCase | ||
|
||
from .factories import SuperUserFactory, UserFactory | ||
|
||
|
||
class AccountAdminTestCase(TestCase): | ||
def test_superuser_ca(self): | ||
"""Test that only superuser can log in to the admin site.""" | ||
simple_user = UserFactory() | ||
self.client.force_login(simple_user) | ||
response = self.client.get("/admin/") | ||
self.assertEqual(response.status_code, 302) | ||
super_user = SuperUserFactory() | ||
self.client.force_login(super_user) | ||
response = self.client.get("/admin/") | ||
self.assertEqual(response.status_code, 200) |
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,14 @@ | ||
from django.test import TestCase | ||
|
||
from .factories import SuperUserFactory, UserFactory | ||
|
||
|
||
class AccountTestCase(TestCase): | ||
def test_is_staff(self): | ||
"""Test that is_staff is same value as is_superuser""" | ||
user = UserFactory() | ||
self.assertFalse(user.is_staff) | ||
self.assertFalse(user.is_superuser) | ||
super_user = SuperUserFactory() | ||
self.assertTrue(super_user.is_staff) | ||
self.assertTrue(super_user.is_superuser) |
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 |
---|---|---|
@@ -1,71 +0,0 @@ | ||
from django_filters.rest_framework import DjangoFilterBackend | ||
from rest_framework import status, viewsets | ||
from rest_framework.decorators import action | ||
from rest_framework.generics import GenericAPIView | ||
from rest_framework.mixins import CreateModelMixin | ||
from rest_framework.response import Response | ||
from rest_framework.reverse import reverse | ||
from rest_framework.viewsets import GenericViewSet | ||
|
||
from project.accounts.models import User | ||
from project.api.filters import EventFilterSet | ||
from project.api.serializers import ( | ||
AccountSerializer, | ||
EventDetailSerializer, | ||
EventListSerializer, | ||
EventTypeSerializer, | ||
SettingsSerializer, | ||
) | ||
from project.events.models import Event, EventType | ||
|
||
|
||
class SettingsApiView(GenericAPIView): | ||
serializer_class = SettingsSerializer | ||
|
||
def get(self, request): | ||
data = {} | ||
event_types = EventType.objects.prefetch_related("sub_types").all() | ||
event_types_serialized = EventTypeSerializer( | ||
event_types, many=True, context={"request": request} | ||
) | ||
data["event_types"] = event_types_serialized.data | ||
data["event_url"] = reverse("api:events-list", request=request) | ||
return Response(data) | ||
|
||
|
||
class EventViewSet(viewsets.ModelViewSet): | ||
filter_backends = (DjangoFilterBackend,) | ||
filterset_class = EventFilterSet | ||
|
||
def get_serializer_class(self): | ||
if self.action == "list": | ||
return EventListSerializer | ||
return EventDetailSerializer | ||
|
||
def get_queryset(self): | ||
qs = Event.objects.all().select_related("source", "event_subtype__event_type") | ||
if self.action not in ["list", "retrieve"] or self.request.user.is_anonymous: | ||
# list and retrieve are public | ||
if self.request.user.is_anonymous: | ||
# anonymous can't change anything | ||
qs = qs.none() | ||
elif not self.request.user.is_staff and not self.request.user.is_superuser: | ||
# nor anonymous, nor admin | ||
qs = self.request.user.events.all() | ||
return qs | ||
|
||
def perform_create(self, serializer): | ||
observer = self.request.user if self.request.user.is_authenticated else None | ||
serializer.save(observer=observer) | ||
|
||
|
||
class AccountViewSet(CreateModelMixin, GenericViewSet): | ||
queryset = User.objects.all() | ||
serializer_class = AccountSerializer | ||
|
||
@action(detail=False, methods=["get"]) | ||
def mine(self, request, *args, **kwargs): | ||
if self.request.user.is_anonymous: | ||
return Response({}, status=status.HTTP_404_NOT_FOUND) | ||
serializer = self.get_serializer(request.user) | ||
return Response(serializer.data) | ||
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,8 @@ | ||
from django.apps import AppConfig | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
|
||
class ApiConfig(AppConfig): | ||
default_auto_field = "django.db.models.BigAutoField" | ||
name = "project.api" | ||
verbose_name = _("API") |
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 |
---|---|---|
@@ -1,12 +1,18 @@ | ||
from django_filters.fields import DateRangeField | ||
from django_filters.rest_framework import FilterSet | ||
from django_filters.rest_framework import FilterSet, filters | ||
|
||
from project.events.models import Event | ||
from project.observations.models import Observation | ||
|
||
|
||
class EventFilterSet(FilterSet): | ||
class ObservationFilterSet(FilterSet): | ||
event_date = DateRangeField() | ||
fields = filters.CharFilter( | ||
method="filter_fields", help_text="filter fields you want to get" | ||
) | ||
|
||
def filter_fields(self, qs): | ||
return qs | ||
|
||
class Meta: | ||
model = Event | ||
fields = ["event_date", "event_subtype"] | ||
model = Observation | ||
fields = ["event_date", "observation_subtype", "fields"] |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
Oops, something went wrong.