Merge pull request #34 from SchrodingersGat/master

Lots of API improvements
This commit is contained in:
Oliver 2017-04-13 00:32:49 +10:00 committed by GitHub
commit b7ab2fa59e
9 changed files with 115 additions and 59 deletions

View File

@ -10,4 +10,5 @@ urlpatterns = [
url(r'^track/', include('track.urls')),
url(r'^project/', include('project.urls')),
url(r'^admin/', admin.site.urls),
url(r'^auth/', include('rest_framework.urls', namespace='rest_framework'))
]

View File

@ -44,10 +44,10 @@ class PartCategoryBriefSerializer(serializers.ModelSerializer):
class PartCategoryDetailSerializer(serializers.ModelSerializer):
# List of parts in this category
parts = PartSerializer(many=True)
parts = PartSerializer(many=True, read_only=True)
# List of child categories under this one
children = PartCategoryBriefSerializer(many=True)
children = PartCategoryBriefSerializer(many=True, read_only=True)
class Meta:
model = PartCategory

View File

@ -1,19 +1,45 @@
from django.conf.urls import url
from django.conf.urls import url, include
from . import views
urlpatterns = [
# Single part detail
url(r'^(?P<pk>[0-9]+)/$', views.PartDetail.as_view()),
# Part parameters list
url(r'^(?P<pk>[0-9]+)/parameters/$', views.PartParameters.as_view()),
""" URL patterns associated with part categories:
/category -> List all top-level categories
/category/<pk> -> Detail view of given category
/category/new -> Create a new category
"""
categorypatterns = [
# Part category detail
url(r'^category/(?P<pk>[0-9]+)/$', views.PartCategoryDetail.as_view()),
# List of top-level categories
url(r'^category/$', views.PartCategoryList.as_view()),
url(r'^$', views.PartCategoryList.as_view())
]
""" URL patterns associated with a particular part:
/part/<pk> -> Detail view of a given part
/part/<pk>/parameters -> List parameters associated with a part
"""
partdetailpatterns = [
# Single part detail
url(r'^$', views.PartDetail.as_view()),
# View part parameters
url(r'parameters/$', views.PartParameters.as_view())
]
""" Top-level URL patterns for the Part app:
/part/ -> List all parts
/part/new -> Create a new part
/part/<pk> -> (refer to partdetailpatterns)
/part/category -> (refer to categorypatterns)
"""
urlpatterns = [
# Individual part
url(r'^(?P<pk>[0-9]+)/', include(partdetailpatterns)),
# Part categories
url(r'^category/', views.PartCategoryList.as_view()),
# List of all parts
url(r'^$', views.PartList.as_view())

View File

@ -1,4 +1,4 @@
from rest_framework import generics
from rest_framework import generics, permissions
from .models import PartCategory, Part, PartParameter
from .serializers import PartSerializer
@ -6,37 +6,44 @@ from .serializers import PartCategoryDetailSerializer
from .serializers import PartParameterSerializer
class PartDetail(generics.RetrieveAPIView):
class PartDetail(generics.RetrieveUpdateDestroyAPIView):
""" Return information on a single part
"""
queryset = Part.objects.all()
serializer_class = PartSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class PartParameters(generics.ListAPIView):
class PartParameters(generics.ListCreateAPIView):
""" Return all parameters associated with a particular part
"""
def get_queryset(self):
part_id = self.kwargs['pk']
return PartParameter.objects.filter(part=part_id)
serializer_class = PartParameterSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class PartList(generics.ListAPIView):
class PartList(generics.ListCreateAPIView):
queryset = Part.objects.all()
serializer_class = PartSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class PartCategoryDetail(generics.RetrieveAPIView):
class PartCategoryDetail(generics.RetrieveUpdateAPIView):
""" Return information on a single PartCategory
"""
queryset = PartCategory.objects.all()
serializer_class = PartCategoryDetailSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class PartCategoryList(generics.ListAPIView):
class PartCategoryList(generics.ListCreateAPIView):
""" Return a list of all top-level part categories.
Categories are considered "top-level" if they do not have a parent
"""
queryset = PartCategory.objects.filter(parent=None)
serializer_class = PartCategoryDetailSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

View File

@ -1,5 +1,5 @@
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
# from django.utils.translation import ugettext as _
from django.db import models
@ -47,6 +47,13 @@ class ProjectPart(models.Model):
The overage is the number of extra parts that are generally used for a single run.
"""
part = models.ForeignKey(Part, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
"""
# TODO - Add overage model fields
# Overage types
OVERAGE_PERCENT = 0
OVERAGE_ABSOLUTE = 1
@ -56,13 +63,11 @@ class ProjectPart(models.Model):
OVERAGE_ABSOLUTE: _("Absolute")
}
part = models.ForeignKey(Part, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
overage = models.FloatField(default=0)
overage_type = models.PositiveIntegerField(
default=OVERAGE_ABSOLUTE,
choices=OVARAGE_CODES.items())
"""
# Set if the part is generated by the project,
# rather than being consumed by the project

View File

@ -11,12 +11,10 @@ class ProjectPartSerializer(serializers.ModelSerializer):
'part',
'project',
'quantity',
'overage',
'overage_type',
'output')
class ProjectBriefSerializer(serializers.ModelSerializer):
class ProjectSerializer(serializers.ModelSerializer):
""" Serializer for displaying brief overview of a project
"""
@ -28,18 +26,6 @@ class ProjectBriefSerializer(serializers.ModelSerializer):
'category')
class ProjectDetailSerializer(serializers.ModelSerializer):
""" Serializer for detailed project information
"""
class Meta:
model = Project
fields = ('pk',
'name',
'description',
'category')
class ProjectCategoryBriefSerializer(serializers.ModelSerializer):
class Meta:
@ -49,9 +35,9 @@ class ProjectCategoryBriefSerializer(serializers.ModelSerializer):
class ProjectCategoryDetailSerializer(serializers.ModelSerializer):
projects = ProjectBriefSerializer(many=True)
projects = ProjectSerializer(many=True, read_only=True)
children = ProjectCategoryBriefSerializer(many=True)
children = ProjectCategoryBriefSerializer(many=True, read_only=True)
class Meta:
model = ProjectCategory

View File

@ -1,20 +1,39 @@
from django.conf.urls import url
from django.conf.urls import url, include
from . import views
urlpatterns = [
""" URL patterns associated with project
/project/<pk> -> Detail view of single project
/project/<pk>/parts -> Detail all parts associated with project
"""
projectdetailpatterns = [
# Single project detail
url(r'^(?P<pk>[0-9]+)/$', views.ProjectDetail.as_view()),
url(r'^$', views.ProjectDetail.as_view()),
# Parts associated with a project
url(r'^(?P<pk>[0-9]+)/parts$', views.ProjectPartsList.as_view()),
url(r'^parts/$', views.ProjectPartsList.as_view()),
]
projectcategorypatterns = [
# List of top-level project categories
url(r'^$', views.ProjectCategoryList.as_view()),
# Detail of a single project category
url(r'^(?P<pk>[0-9]+)/$', views.ProjectCategoryDetail.as_view()),
# Create a new category
url(r'^new/$', views.NewProjectCategory.as_view())
]
urlpatterns = [
# Individual project URL
url(r'^(?P<pk>[0-9]+)/', include(projectdetailpatterns)),
# List of all projects
url(r'^$', views.ProjectList.as_view()),
# List of top-level project categories
url(r'^category/$', views.ProjectCategoryList.as_view()),
# Detail of a single project category
url(r'^category/(?P<pk>[0-9]+)/$', views.ProjectCategoryDetail.as_view())
# Project categories
url(r'^category/', include(projectcategorypatterns)),
]

View File

@ -1,38 +1,50 @@
from rest_framework import generics
from rest_framework import generics, permissions
from .models import ProjectCategory, Project, ProjectPart
from .serializers import ProjectBriefSerializer, ProjectDetailSerializer
from .serializers import ProjectSerializer
from .serializers import ProjectCategoryDetailSerializer
from .serializers import ProjectPartSerializer
class ProjectDetail(generics.RetrieveAPIView):
class ProjectDetail(generics.RetrieveUpdateAPIView):
queryset = Project.objects.all()
serializer_class = ProjectDetailSerializer
serializer_class = ProjectSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectList(generics.ListAPIView):
class ProjectList(generics.ListCreateAPIView):
queryset = Project.objects.all()
serializer_class = ProjectBriefSerializer
serializer_class = ProjectSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectCategoryDetail(generics.RetrieveAPIView):
class NewProjectCategory(generics.CreateAPIView):
""" Create a new Project Category
"""
serializer_class = ProjectCategoryDetailSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectCategoryDetail(generics.RetrieveUpdateAPIView):
queryset = ProjectCategory.objects.all()
serializer_class = ProjectCategoryDetailSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectCategoryList(generics.ListAPIView):
class ProjectCategoryList(generics.ListCreateAPIView):
queryset = ProjectCategory.objects.filter(parent=None)
serializer_class = ProjectCategoryDetailSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class ProjectPartsList(generics.ListAPIView):
class ProjectPartsList(generics.ListCreateAPIView):
serializer_class = ProjectPartSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get_queryset(self):
project_id = self.kwargs['pk']

View File

@ -36,10 +36,10 @@ class LocationDetailSerializer(serializers.ModelSerializer):
"""
# List of all stock items in this location
items = StockItemSerializer(many=True)
items = StockItemSerializer(many=True, read_only=True)
# List of all child locations under this one
children = LocationBriefSerializer(many=True)
children = LocationBriefSerializer(many=True, read_only=True)
class Meta:
model = StockLocation