Skip to content

Commit 8840ce3

Browse files
author
Matt Elwell
committed
Merge branch 'feature/refactor-project-features-view' into develop
# Conflicts: # src/features/views.py # src/projects/views.py
2 parents 048eb63 + 22a6bd0 commit 8840ce3

7 files changed

Lines changed: 59 additions & 63 deletions

File tree

src/api/tests.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ def test_should_remove_identityfeature_when_delete(self):
278278

279279
class ProjectFeatureTestCase(TestCase):
280280
project_features_url = '/api/v1/projects/%s/features/'
281+
project_feature_detail_url = '/api/v1/projects/%s/features/%d/'
281282
post_template = '{ "name": "%s", "project": %d, "initial_value": "%s" }'
282283

283284
def set_up(self):
@@ -341,12 +342,12 @@ def test_should_delete_feature_states_when_feature_deleted(self):
341342
feature = Feature.objects.get(name="test feature", project=project.id)
342343

343344
# When
344-
response = client.delete(self.project_features_url % project.id, data='{"id": %d}' %
345-
feature.id,
345+
response = client.delete(self.project_feature_detail_url % (project.id, feature.id),
346+
data='{"id": %d}' % feature.id,
346347
content_type='application/json')
347348

348349
# Then
349-
self.assertEquals(response.status_code, status.HTTP_200_OK)
350+
self.assertEquals(response.status_code, status.HTTP_204_NO_CONTENT)
350351
# check feature was deleted succesfully
351352
self.assertEquals(0, Feature.objects.filter(name="test feature",
352353
project=project.id).count())
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.14 on 2018-08-15 10:11
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('features', '0008_auto_20180608_1328'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='feature',
17+
name='description',
18+
field=models.TextField(blank=True, null=True),
19+
),
20+
]

src/features/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Feature(models.Model):
2929
created_date = models.DateTimeField('DateCreated', auto_now_add=True)
3030
project = models.ForeignKey(Project, related_name='features')
3131
initial_value = models.CharField(max_length=2000, null=True, default=None)
32-
description = models.TextField(null=True)
32+
description = models.TextField(null=True, blank=True)
3333
default_enabled = models.BooleanField(default=False)
3434
type = models.CharField(max_length=50, choices=FEATURE_TYPES, default=FLAG)
3535

src/features/serializers.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
from .models import Feature, FeatureState, FeatureStateValue
44

55

6-
class FeatureSerializer(serializers.ModelSerializer):
6+
class CreateFeatureSerializer(serializers.ModelSerializer):
77
class Meta:
88
model = Feature
99
fields = "__all__"
1010

1111
def validate(self, data):
12-
data = super(FeatureSerializer, self).validate(data)
12+
data = super(CreateFeatureSerializer, self).validate(data)
1313

1414
if Feature.objects.filter(project=data['project'], name__iexact=data['name']).exists():
1515
raise serializers.ValidationError("Feature with that name already exists for this "
@@ -19,8 +19,14 @@ def validate(self, data):
1919
return data
2020

2121

22+
class FeatureSerializer(serializers.ModelSerializer):
23+
class Meta:
24+
model = Feature
25+
fields = "__all__"
26+
27+
2228
class FeatureStateSerializerFull(serializers.ModelSerializer):
23-
feature = FeatureSerializer()
29+
feature = CreateFeatureSerializer()
2430
feature_state_value = serializers.SerializerMethodField()
2531

2632
class Meta:

src/features/views.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,25 @@
66
from rest_framework.schemas import AutoSchema
77

88
from environments.models import Environment, Identity
9+
from projects.models import Project
910
from .models import FeatureState, Feature
10-
from .serializers import FeatureStateSerializerBasic, FeatureStateValueSerializer, \
11-
FeatureStateSerializerFull, FeatureStateSerializerCreate
11+
from .serializers import FeatureStateSerializerBasic, FeatureStateSerializerFull, \
12+
FeatureStateSerializerCreate, CreateFeatureSerializer, FeatureSerializer, \
13+
FeatureStateValueSerializer
14+
15+
16+
class FeatureViewSet(viewsets.ModelViewSet):
17+
queryset = Feature.objects.all()
18+
19+
def get_serializer_class(self):
20+
if self.action == 'create':
21+
return CreateFeatureSerializer
22+
else:
23+
return FeatureSerializer
24+
25+
def get_queryset(self):
26+
project = Project.objects.get(pk=self.kwargs['project_pk'])
27+
return project.features.all()
1228

1329

1430
class FeatureStateViewSet(viewsets.ModelViewSet):

src/projects/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
from django.conf.urls import url, include
22
from rest_framework_nested import routers
3+
4+
from features.views import FeatureViewSet
35
from . import views
46

57

68
router = routers.DefaultRouter()
79
router.register(r'', views.ProjectViewSet, base_name="project")
810

11+
projects_router = routers.NestedSimpleRouter(router, r'', lookup="project")
12+
projects_router.register(r'features', FeatureViewSet, base_name="project-features")
13+
914
app_name = "projects"
1015

1116
urlpatterns = [
1217
url(r'^', include(router.urls)),
18+
url(r'^', include(projects_router.urls))
1319
]

src/projects/views.py

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
from rest_framework.decorators import action
66
from rest_framework.response import Response
77

8-
from features.models import Feature, FeatureState, FLAG
9-
from features.serializers import FeatureSerializer
108
from environments.serializers import EnvironmentSerializerLight
119
from projects.models import Project
1210
from projects.serializers import ProjectSerializer
@@ -26,55 +24,4 @@ def get_queryset(self):
2624
def environments(self, request, pk):
2725
project = self.get_object()
2826
environments = project.environments.all()
29-
return Response(EnvironmentSerializerLight(environments, many=True).data)
30-
31-
@action(detail=True, methods=["GET", "POST", "PUT", "DELETE"])
32-
def features(self, request, pk):
33-
project = self.get_object()
34-
35-
self.queryset = Feature.objects.filter(project=project)
36-
self.serializer_class = FeatureSerializer
37-
38-
if request.method == "POST":
39-
data = {
40-
"project": project.id,
41-
"name": request.data["name"],
42-
"initial_value": request.data.get("initial_value"),
43-
"description": request.data.get("description"),
44-
"type": request.data.get("type", FLAG),
45-
"default_enabled": request.data.get("default_enabled", False),
46-
}
47-
48-
f_serializer = FeatureSerializer(data=data)
49-
50-
if f_serializer.is_valid():
51-
f_serializer.save()
52-
return Response(f_serializer.data, status=status.HTTP_201_CREATED)
53-
else:
54-
return Response(f_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
55-
56-
elif request.method == "PUT":
57-
data = {
58-
"id": request.data["id"],
59-
"project": project.id,
60-
"name": request.data["name"],
61-
"initial_value": request.data["initial_value"]
62-
}
63-
64-
serializer = FeatureSerializer(data=data)
65-
66-
if serializer.is_valid():
67-
feature_to_update = Feature.objects.get(pk=data["id"])
68-
feature_updated = serializer.update(feature_to_update, serializer.validated_data)
69-
return Response(FeatureSerializer(feature_updated).data,
70-
status=status.HTTP_201_CREATED)
71-
else:
72-
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
73-
74-
elif request.method == "DELETE":
75-
Feature.objects.get(pk=request.data["id"]).delete()
76-
return Response(status=status.HTTP_200_OK)
77-
78-
else:
79-
serializer = FeatureSerializer(instance=self.queryset, many=True)
80-
return Response(serializer.data)
27+
return Response(EnvironmentSerializerLight(environments, many=True).data)

0 commit comments

Comments
 (0)