Updated API URLs

This commit is contained in:
Oliver 2017-04-11 09:41:03 +10:00
parent 9a9a039fc9
commit e06121ebda
9 changed files with 144 additions and 71 deletions

View File

@ -0,0 +1,12 @@
from django.conf.urls import url, include
from django.contrib import admin
admin.site.site_header = "InvenTree Admin"
urlpatterns = [
url(r'^stock/', include('stock.urls')),
url(r'^part/', include('part.api_urls')),
url(r'^supplier/', include('supplier.urls')),
url(r'^track/', include('track.urls')),
url(r'^project/', include('project.api_urls'))
]

View File

@ -8,10 +8,10 @@ from django.contrib.contenttypes.models import ContentType
class Company(models.Model):
""" Abstract model representing an external company
"""
class Meta:
abstract = True
name = models.CharField(max_length=100)
URL = models.URLField(blank=True)
address = models.CharField(max_length=200,
@ -33,10 +33,10 @@ class InvenTreeTree(models.Model):
- Each Category has one parent Category, which can be blank (for a top-level Category).
- Each Category can have zero-or-more child Categor(y/ies)
"""
class Meta:
abstract = True
name = models.CharField(max_length=100)
description = models.CharField(max_length=250, blank=True)
parent = models.ForeignKey('self',
@ -44,95 +44,102 @@ class InvenTreeTree(models.Model):
blank=True,
null=True,
related_name='children')
def getUniqueParents(self, unique=None):
""" Return a flat set of all parent items that exist above this node.
If any parents are repeated (which would be very bad!), the process is halted
"""
if unique is None:
unique = set()
else:
unique.add(self.id)
if self.parent and self.parent.id not in unique:
self.parent.getUniqueParents(unique)
return unique
def getUniqueChildren(self, unique=None):
""" Return a flat set of all child items that exist under this node.
If any child items are repeated, the repetitions are omitted.
"""
if unique is None:
unique = set()
if self.id in unique:
return unique
unique.add(self.id)
# Some magic to get around the limitations of abstract models
contents = ContentType.objects.get_for_model(type(self))
children = contents.get_all_objects_for_this_type(parent=self.id)
return unique
@property
def children(self):
contents = ContentType.objects.get_for_model(type(self))
children = contents.get_all_objects_for_this_type(parent=self.id)
return children
def getAcceptableParents(self):
""" Returns a list of acceptable parent items within this model
Acceptable parents are ones which are not underneath this item.
Setting the parent of an item to its own child results in recursion.
"""
contents = ContentType.objects.get_for_model(type(self))
available = contents.get_all_objects_for_this_type()
# List of child IDs
childs = getUniqueChildren()
acceptable = [None]
for a in available:
if a.id not in childs:
acceptable.append(a)
return acceptable
@property
def parentpath(self):
""" Return the parent path of this category
Todo:
This function is recursive and expensive.
It should be reworked such that only a single db call is required
"""
if self.parent:
return self.parent.parentpath + [self.parent]
else:
return []
@property
def path(self):
if self.parent:
return "/".join([p.name for p in self.parentpath]) + "/" + self.name
else:
return self.name
def __setattr__(self, attrname, val):
""" Custom Attribute Setting function
Parent:
Setting the parent of an item to its own child results in an infinite loop.
The parent of an item cannot be set to:
a) Its own ID
b) The ID of any child items that exist underneath it
Name:
Tree node names are limited to a reduced character set
"""
if attrname == 'parent_id':
# If current ID is None, continue
# - This object is just being created
@ -153,14 +160,14 @@ class InvenTreeTree(models.Model):
# Prohibit certain characters from tree node names
elif attrname == 'name':
val = val.translate({ord(c): None for c in "!@#$%^&*'\"\\/[]{}<>,|+=~`"})
super(InvenTreeTree, self).__setattr__(attrname, val)
def __str__(self):
""" String representation of a category is the full path to that category
Todo:
This is recursive - Make it not so.
"""
return self.path

View File

@ -1,25 +1,10 @@
"""InvenTree URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin
admin.site.site_header = "InvenTree Admin"
urlpatterns = [
url(r'^api/', include('InvenTree.api_urls')),
url(r'^stock/', include('stock.urls')),
url(r'^part/', include('part.urls')),
url(r'^supplier/', include('supplier.urls')),

View File

@ -0,0 +1,17 @@
from django.conf.urls import url
from . import views
urlpatterns = [
# Display part detail
url(r'^(?P<pk>[0-9]+)/$', views.PartDetail.as_view()),
# Display a single part category
url(r'^category/(?P<pk>[0-9]+)/$', views.PartCategoryDetail.as_view()),
# Display a list of top-level categories
url(r'^category/$', views.PartCategoryList.as_view()),
# Display list of all parts
url(r'^$', views.PartList.as_view())
]

View File

@ -15,6 +15,12 @@ class PartCategory(InvenTreeTree):
verbose_name = "Part Category"
verbose_name_plural = "Part Categories"
@property
def parts(self):
parts_list = self.part_set.all()
print(parts_list)
return parts_list
class Part(models.Model):
""" Represents a """

View File

@ -4,14 +4,21 @@ from .models import Part, PartCategory, PartParameter
class ParameterSerializer(serializers.ModelSerializer):
""" Serializer for a PartParameter
"""
class Meta:
model = PartParameter
fields = ('name',
fields = ('pk',
'name',
'value',
'units')
class PartSerializer(serializers.ModelSerializer):
class PartDetailSerializer(serializers.ModelSerializer):
""" Serializer for complete detail information of a part.
Used when displaying all details of a single component.
"""
params = ParameterSerializer(source='parameters', many=True)
@ -26,11 +33,44 @@ class PartSerializer(serializers.ModelSerializer):
'params')
class PartCategorySerializer(serializers.ModelSerializer):
class PartBriefSerializer(serializers.ModelSerializer):
""" Serializer for displaying overview of a part.
Used e.g. for displaying list of parts in a category.
"""
class Meta:
model = Part
fields = ('pk',
'name',
'IPN',
'description',
'category',
'stock')
class PartCategoryBriefSerializer(serializers.ModelSerializer):
class Meta:
model = PartCategory
fields = ('pk',
'name',
'description')
class PartCategoryDetailSerializer(serializers.ModelSerializer):
# List of parts in this category
parts = PartBriefSerializer(many=True)
# List of child categories under this one
children = PartCategoryBriefSerializer(many=True)
class Meta:
model = PartCategory
fields = ('pk',
'name',
'description',
'parent',
'path')
'path',
'children',
'parts')

View File

@ -3,15 +3,9 @@ from django.conf.urls import url
from . import views
urlpatterns = [
# Display part detail
url(r'^(?P<pk>[0-9]+)/$', views.PartDetail.as_view()),
# Display a single part category
url(r'^category/(?P<pk>[0-9]+)/$', views.PartCategoryDetail.as_view()),
# Display a list of top-level categories
url(r'^category/$', views.PartCategoryList.as_view()),
# Display list of parts
url(r'^$', views.PartList.as_view())
# part landing page
url(r'^$', views.part_index),
# part category landing page
url(r'^category/$', views.category_index)
]

View File

@ -4,32 +4,38 @@ from django.http import HttpResponse, Http404
from rest_framework import generics
from .models import PartCategory, Part
from .serializers import PartSerializer, PartCategorySerializer
from .serializers import PartBriefSerializer, PartDetailSerializer
from .serializers import PartCategoryBriefSerializer, PartCategoryDetailSerializer
def index(request):
def part_index(request):
return HttpResponse("Hello world. This is the parts page")
def category_index(request):
return HttpResponse("This is the category page")
class PartDetail(generics.RetrieveAPIView):
queryset = Part.objects.all()
serializer_class = PartSerializer
serializer_class = PartDetailSerializer
class PartList(generics.ListAPIView):
queryset = Part.objects.all()
serializer_class = PartSerializer
serializer_class = PartBriefSerializer
class PartCategoryDetail(generics.RetrieveAPIView):
""" Return information on a single PartCategory
"""
queryset = PartCategory.objects.all()
serializer_class = PartCategorySerializer
serializer_class = PartCategoryDetailSerializer
class PartCategoryList(generics.ListAPIView):
queryset = PartCategory.objects.all()
serializer_class = PartCategorySerializer
""" 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 = PartCategoryBriefSerializer

View File

@ -0,0 +1,6 @@
from django.conf.urls import url
from . import views
urlpatterns = [
]