refactor: Split people.views into multiple modules

This commit is contained in:
James Graham
2020-03-27 15:15:18 +00:00
parent 7c75f9d7f4
commit 2cdc7675c7
5 changed files with 178 additions and 149 deletions

View File

@@ -7,46 +7,46 @@ app_name = 'people'
urlpatterns = [
path('profile/',
views.ProfileView.as_view(),
views.person.ProfileView.as_view(),
name='person.profile'),
path('people/create',
views.PersonCreateView.as_view(),
views.person.PersonCreateView.as_view(),
name='person.create'),
path('people',
views.PersonListView.as_view(),
views.person.PersonListView.as_view(),
name='person.list'),
path('people/<int:pk>',
views.ProfileView.as_view(),
views.person.ProfileView.as_view(),
name='person.detail'),
path('people/<int:pk>/update',
views.PersonUpdateView.as_view(),
views.person.PersonUpdateView.as_view(),
name='person.update'),
path('people/<int:person_pk>/relationships/create',
views.RelationshipCreateView.as_view(),
views.relationship.RelationshipCreateView.as_view(),
name='person.relationship.create'),
path('relationships/<int:pk>',
views.RelationshipDetailView.as_view(),
views.relationship.RelationshipDetailView.as_view(),
name='relationship.detail'),
path('relationships/<int:relationship_pk>/update',
views.RelationshipUpdateView.as_view(),
views.relationship.RelationshipUpdateView.as_view(),
name='relationship.update'),
path('api/people',
views.PersonApiView.as_view(),
views.person.PersonApiView.as_view(),
name='person.api.list'),
path('api/relationships',
views.RelationshipApiView.as_view(),
views.relationship.RelationshipApiView.as_view(),
name='relationship.api.list'),
path('network',
views.NetworkView.as_view(),
views.network.NetworkView.as_view(),
name='network'),
]

9
people/views/__init__.py Normal file
View File

@@ -0,0 +1,9 @@
"""
Views for displaying or manipulating models within the `people` app.
"""
from . import (
network,
person,
relationship
)

72
people/views/network.py Normal file
View File

@@ -0,0 +1,72 @@
"""
Views for displaying networks of :class:`People` and :class:`Relationship`s.
"""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.utils import timezone
from django.views.generic import FormView
from people import forms, models, serializers
class NetworkView(LoginRequiredMixin, FormView):
"""
View to display relationship network.
"""
template_name = 'people/network.html'
form_class = forms.NetworkFilterForm
def get_form_kwargs(self):
"""
Add GET params to form data.
"""
kwargs = super().get_form_kwargs()
if self.request.method == 'GET':
if 'data' in kwargs:
kwargs['data'].update(self.request.GET)
else:
kwargs['data'] = self.request.GET
return kwargs
def get_context_data(self, **kwargs):
"""
Add filtered QuerySets of :class:`Person` and :class:`Relationship` to the context.
"""
context = super().get_context_data(**kwargs)
form = context['form']
at_time = timezone.now()
relationship_set = models.Relationship.objects.all()
# Filter answers to relationship questions
for key, value in form.data.items():
if key.startswith('question_') and value:
question_id = key.replace('question_', '', 1)
answer = models.RelationshipQuestionChoice.objects.get(pk=value,
question__pk=question_id)
relationship_set = relationship_set.filter(
Q(answer_sets__replaced_timestamp__gt=at_time) | Q(answer_sets__replaced_timestamp__isnull=True),
answer_sets__timestamp__lte=at_time,
answer_sets__question_answers=answer
)
context['person_set'] = serializers.PersonSerializer(
models.Person.objects.all(),
many=True
).data
context['relationship_set'] = serializers.RelationshipSerializer(
relationship_set,
many=True
).data
return context
def form_valid(self, form):
return self.render_to_response(self.get_context_data())

78
people/views/person.py Normal file
View File

@@ -0,0 +1,78 @@
"""
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
class PersonCreateView(CreateView):
"""
View to create a new instance of :class:`Person`.
If 'user' is passed as a URL parameter - link the new person to the current user.
"""
model = models.Person
template_name = 'people/person/create.html'
form_class = forms.PersonForm
def form_valid(self, form):
if 'user' in self.request.GET:
form.instance.user = self.request.user
return super().form_valid(form)
class PersonListView(ListView):
"""
View displaying a list of :class:`Person` objects - searchable.
"""
model = models.Person
template_name = 'people/person/list.html'
class ProfileView(permissions.UserIsLinkedPersonMixin, DetailView):
"""
View displaying the profile of a :class:`Person` - who may be a user.
"""
model = models.Person
template_name = 'people/person/detail.html'
def get_object(self, queryset=None) -> models.Person:
"""
Get the :class:`Person` object to be represented by this page.
If not determined from url get current user.
"""
try:
return super().get_object(queryset)
except AttributeError:
# pk was not provided in URL
return self.request.user.person
class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView):
"""
View for updating a :class:`Person` record.
"""
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)

View File

@@ -1,71 +1,14 @@
"""
Views for displaying or manipulating models in the 'people' app.
Views for displaying or manipulating instances of :class:`Relationship`.
"""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone
from django.views.generic import CreateView, DetailView, FormView, ListView, UpdateView
from django.views.generic import CreateView, DetailView
from rest_framework.views import APIView, Response
from . import forms, models, permissions, serializers
class PersonCreateView(CreateView):
"""
View to create a new instance of :class:`Person`.
If 'user' is passed as a URL parameter - link the new person to the current user.
"""
model = models.Person
template_name = 'people/person/create.html'
form_class = forms.PersonForm
def form_valid(self, form):
if 'user' in self.request.GET:
form.instance.user = self.request.user
return super().form_valid(form)
class PersonListView(ListView):
"""
View displaying a list of :class:`Person` objects - searchable.
"""
model = models.Person
template_name = 'people/person/list.html'
class ProfileView(permissions.UserIsLinkedPersonMixin, DetailView):
"""
View displaying the profile of a :class:`Person` - who may be a user.
"""
model = models.Person
template_name = 'people/person/detail.html'
def get_object(self, queryset=None) -> models.Person:
"""
Get the :class:`Person` object to be represented by this page.
If not determined from url get current user.
"""
try:
return super().get_object(queryset)
except AttributeError:
# pk was not provided in URL
return self.request.user.person
class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView):
"""
View for updating a :class:`Person` record.
"""
model = models.Person
template_name = 'people/person/update.html'
form_class = forms.PersonForm
from people import forms, models, permissions, serializers
class RelationshipDetailView(permissions.UserIsLinkedPersonMixin, DetailView):
@@ -165,12 +108,12 @@ class RelationshipUpdateView(permissions.UserIsLinkedPersonMixin, CreateView):
context['relationship'] = self.relationship
return context
def get_initial(self):
initial = super().get_initial()
initial['relationship'] = self.relationship
return initial
def form_valid(self, form):
@@ -187,25 +130,13 @@ class RelationshipUpdateView(permissions.UserIsLinkedPersonMixin, CreateView):
answer_set.save()
return response
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)
class RelationshipApiView(APIView):
"""
List all :class:`Relationship` instances.
"""
def get(self, request, format=None):
"""
List all :class:`Relationship` instances.
@@ -213,64 +144,3 @@ class RelationshipApiView(APIView):
serializer = serializers.RelationshipSerializer(models.Relationship.objects.all(),
many=True)
return Response(serializer.data)
class NetworkView(LoginRequiredMixin, FormView):
"""
View to display relationship network.
"""
template_name = 'people/network.html'
form_class = forms.NetworkFilterForm
def get_form_kwargs(self):
"""
Add GET params to form data.
"""
kwargs = super().get_form_kwargs()
if self.request.method == 'GET':
if 'data' in kwargs:
kwargs['data'].update(self.request.GET)
else:
kwargs['data'] = self.request.GET
return kwargs
def get_context_data(self, **kwargs):
"""
Add filtered QuerySets of :class:`Person` and :class:`Relationship` to the context.
"""
context = super().get_context_data(**kwargs)
form = context['form']
at_time = timezone.now()
relationship_set = models.Relationship.objects.all()
# Filter answers to relationship questions
for key, value in form.data.items():
if key.startswith('question_') and value:
question_id = key.replace('question_', '', 1)
answer = models.RelationshipQuestionChoice.objects.get(pk=value,
question__pk=question_id)
relationship_set = relationship_set.filter(
Q(answer_sets__replaced_timestamp__gt=at_time) | Q(answer_sets__replaced_timestamp__isnull=True),
answer_sets__timestamp__lte=at_time,
answer_sets__question_answers=answer
)
context['person_set'] = serializers.PersonSerializer(
models.Person.objects.all(),
many=True
).data
context['relationship_set'] = serializers.RelationshipSerializer(
relationship_set,
many=True
).data
return context
def form_valid(self, form):
return self.render_to_response(self.get_context_data())