From da57108e3e8cf4ff03cbd7b79b62d69d293ab441 Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 27 Mar 2020 17:00:37 +0000 Subject: [PATCH] refactor: Use custom CSV export view Remove dependency on djangorestframework-csv --- breccia_mapper/templates/export.html | 4 ++-- people/serializers.py | 15 +++++-------- people/urls.py | 12 +++++----- people/views/__init__.py | 1 + people/views/export.py | 33 ++++++++++++++++++++++++++++ people/views/person.py | 18 +-------------- people/views/relationship.py | 18 +-------------- requirements.txt | 2 -- 8 files changed, 50 insertions(+), 53 deletions(-) create mode 100644 people/views/export.py diff --git a/breccia_mapper/templates/export.html b/breccia_mapper/templates/export.html index c552ced..e0aca40 100644 --- a/breccia_mapper/templates/export.html +++ b/breccia_mapper/templates/export.html @@ -24,7 +24,7 @@ Export + href="{% url 'people:person.export' %}">Export @@ -33,7 +33,7 @@ Export + href="{% url 'people:relationship.export' %}">Export diff --git a/people/serializers.py b/people/serializers.py index b3f6c4f..85e1c27 100644 --- a/people/serializers.py +++ b/people/serializers.py @@ -16,24 +16,21 @@ class PersonSerializer(serializers.ModelSerializer): ] -class MinimalPersonSerializer(serializers.ModelSerializer): - """ - Serializer containing just the necessary fields to identify a :class:`Person`. - - Used for nesting within other serializers. - """ +class PersonExportSerializer(serializers.ModelSerializer): class Meta: model = models.Person fields = [ 'pk', 'name', + 'core_member', + 'gender', + 'age_group', + 'nationality', + 'country_of_residence', ] class RelationshipSerializer(serializers.ModelSerializer): - source = MinimalPersonSerializer() - target = MinimalPersonSerializer() - class Meta: model = models.Relationship fields = [ diff --git a/people/urls.py b/people/urls.py index d484424..784522c 100644 --- a/people/urls.py +++ b/people/urls.py @@ -38,13 +38,13 @@ urlpatterns = [ views.relationship.RelationshipUpdateView.as_view(), name='relationship.update'), - path('api/people', - views.person.PersonApiView.as_view(), - name='person.api.list'), + path('people/export', + views.export.PersonExportView.as_view(), + name='person.export'), - path('api/relationships', - views.relationship.RelationshipApiView.as_view(), - name='relationship.api.list'), + path('relationships/export', + views.export.RelationshipExportView.as_view(), + name='relationship.export'), path('network', views.network.NetworkView.as_view(), diff --git a/people/views/__init__.py b/people/views/__init__.py index 39dd5c9..5dd2c46 100644 --- a/people/views/__init__.py +++ b/people/views/__init__.py @@ -3,6 +3,7 @@ Views for displaying or manipulating models within the `people` app. """ from . import ( + export, network, person, relationship diff --git a/people/views/export.py b/people/views/export.py new file mode 100644 index 0000000..343b7f7 --- /dev/null +++ b/people/views/export.py @@ -0,0 +1,33 @@ +import csv +import typing + +from django.http import HttpResponse +from django.views.generic.list import BaseListView + +from .. import models, serializers + + +class CsvExportView(BaseListView): + model = None + serializer_class = None + + def render_to_response(self, context: typing.Dict) -> HttpResponse: + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = f'attachment; filename="{self.get_context_object_name(self.object_list)}.csv"' + + serializer = self.serializer_class(self.get_queryset(), many=True) + writer = csv.DictWriter(response, fieldnames=self.serializer_class.Meta.fields) + writer.writeheader() + writer.writerows(serializer.data) + + return response + + +class PersonExportView(CsvExportView): + model = models.Person + serializer_class = serializers.PersonExportSerializer + + +class RelationshipExportView(CsvExportView): + model = models.Relationship + serializer_class = serializers.RelationshipSerializer diff --git a/people/views/person.py b/people/views/person.py index c868e9d..1ba28f5 100644 --- a/people/views/person.py +++ b/people/views/person.py @@ -4,9 +4,7 @@ Views for displaying or manipulating instances of :class:`Person`. from django.views.generic import CreateView, DetailView, ListView, UpdateView -from rest_framework.views import APIView, Response - -from people import forms, models, permissions, serializers +from people import forms, models, permissions class PersonCreateView(CreateView): @@ -62,17 +60,3 @@ class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView): model = models.Person template_name = 'people/person/update.html' form_class = forms.PersonForm - - -class PersonApiView(APIView): - """ - List all :class:`Person` instances. - """ - - def get(self, request, format=None): - """ - List all :class:`Person` instances. - """ - serializer = serializers.PersonSerializer(models.Person.objects.all(), - many=True) - return Response(serializer.data) diff --git a/people/views/relationship.py b/people/views/relationship.py index 3e2c7d5..eeb2ea6 100644 --- a/people/views/relationship.py +++ b/people/views/relationship.py @@ -6,9 +6,7 @@ from django.urls import reverse from django.utils import timezone from django.views.generic import CreateView, DetailView -from rest_framework.views import APIView, Response - -from people import forms, models, permissions, serializers +from people import forms, models, permissions class RelationshipDetailView(permissions.UserIsLinkedPersonMixin, DetailView): @@ -130,17 +128,3 @@ class RelationshipUpdateView(permissions.UserIsLinkedPersonMixin, CreateView): answer_set.save() return response - - -class RelationshipApiView(APIView): - """ - List all :class:`Relationship` instances. - """ - - def get(self, request, format=None): - """ - List all :class:`Relationship` instances. - """ - serializer = serializers.RelationshipSerializer(models.Relationship.objects.all(), - many=True) - return Response(serializer.data) diff --git a/requirements.txt b/requirements.txt index fb959e2..1c63c7e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,6 @@ django-picklefield==2.1.1 django-select2==7.2.0 django-settings-export==1.2.1 djangorestframework==3.11.0 -djangorestframework-csv==2.1.0 dodgy==0.2.1 isort==4.3.21 lazy-object-proxy==1.4.3 @@ -39,5 +38,4 @@ snowballstemmer==2.0.0 soupsieve==1.9.5 sqlparse==0.3.0 typed-ast==1.4.1 -unicodecsv==0.14.1 wrapt==1.11.2