2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 20:16:44 +00:00

Annotate models with their API list view

- It will make sense, trust me
This commit is contained in:
Oliver 2021-06-25 00:17:58 +10:00
parent b273dc613b
commit 04374c71c2
12 changed files with 153 additions and 5 deletions

View File

@ -60,6 +60,10 @@ class Build(MPTTModel):
responsible: User (or group) responsible for completing the build responsible: User (or group) responsible for completing the build
""" """
@staticmethod
def get_api_url():
return reverse('api-build-list')
OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
class Meta: class Meta:
@ -1117,6 +1121,10 @@ class BuildItem(models.Model):
quantity: Number of units allocated quantity: Number of units allocated
""" """
@staticmethod
def get_api_url():
return reverse('api-build-item-list')
def get_absolute_url(self): def get_absolute_url(self):
# TODO - Fix! # TODO - Fix!
return '/build/item/{pk}/'.format(pk=self.id) return '/build/item/{pk}/'.format(pk=self.id)

View File

@ -424,7 +424,7 @@ company_api_urls = [
url(r'^part/', include(supplier_part_api_urls)), url(r'^part/', include(supplier_part_api_urls)),
url(r'^price-break/', SupplierPriceBreakList.as_view(), name='api-part-supplier-price'), url(r'^price-break/', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'),
url(r'^(?P<pk>\d+)/?', CompanyDetail.as_view(), name='api-company-detail'), url(r'^(?P<pk>\d+)/?', CompanyDetail.as_view(), name='api-company-detail'),

View File

@ -84,6 +84,10 @@ class Company(models.Model):
currency_code: Specifies the default currency for the company currency_code: Specifies the default currency for the company
""" """
@staticmethod
def get_api_url():
return reverse('api-company-list')
class Meta: class Meta:
ordering = ['name', ] ordering = ['name', ]
constraints = [ constraints = [
@ -297,6 +301,10 @@ class ManufacturerPart(models.Model):
description: Descriptive notes field description: Descriptive notes field
""" """
@staticmethod
def get_api_url():
return reverse('api-manufacturer-part-list')
class Meta: class Meta:
unique_together = ('part', 'manufacturer', 'MPN') unique_together = ('part', 'manufacturer', 'MPN')
@ -380,6 +388,10 @@ class ManufacturerPartParameter(models.Model):
Each parameter is a simple string (text) value. Each parameter is a simple string (text) value.
""" """
@staticmethod
def get_api_url():
return reverse('api-manufacturer-part-parameter-list')
class Meta: class Meta:
unique_together = ('manufacturer_part', 'name') unique_together = ('manufacturer_part', 'name')
@ -432,6 +444,10 @@ class SupplierPart(models.Model):
packaging: packaging that the part is supplied in, e.g. "Reel" packaging: packaging that the part is supplied in, e.g. "Reel"
""" """
@staticmethod
def get_api_url():
return reverse('api-supplier-part-list')
def get_absolute_url(self): def get_absolute_url(self):
return reverse('supplier-part-detail', kwargs={'pk': self.id}) return reverse('supplier-part-detail', kwargs={'pk': self.id})
@ -660,6 +676,10 @@ class SupplierPriceBreak(common.models.PriceBreak):
currency: Reference to the currency of this pricebreak (leave empty for base currency) currency: Reference to the currency of this pricebreak (leave empty for base currency)
""" """
@staticmethod
def get_api_url():
return reverse('api-part-supplier-price-list')
part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks', verbose_name=_('Part'),) part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks', verbose_name=_('Part'),)
class Meta: class Meta:

View File

@ -39,7 +39,7 @@ $('#price-break-table').inventreeTable({
queryParams: { queryParams: {
part: {{ part.id }}, part: {{ part.id }},
}, },
url: "{% url 'api-part-supplier-price' %}", url: "{% url 'api-part-supplier-price-list' %}",
onPostBody: function() { onPostBody: function() {
var table = $('#price-break-table'); var table = $('#price-break-table');

View File

@ -12,6 +12,7 @@ import datetime
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.urls import reverse
from django.core.validators import FileExtensionValidator, MinValueValidator from django.core.validators import FileExtensionValidator, MinValueValidator
from django.core.exceptions import ValidationError, FieldError from django.core.exceptions import ValidationError, FieldError
@ -237,6 +238,10 @@ class StockItemLabel(LabelTemplate):
Template for printing StockItem labels Template for printing StockItem labels
""" """
@staticmethod
def get_api_url():
return reverse('api-stockitem-label-list')
SUBDIR = "stockitem" SUBDIR = "stockitem"
filters = models.CharField( filters = models.CharField(
@ -290,6 +295,10 @@ class StockLocationLabel(LabelTemplate):
Template for printing StockLocation labels Template for printing StockLocation labels
""" """
@staticmethod
def get_api_url():
return reverse('api-stocklocation-label-list')
SUBDIR = "stocklocation" SUBDIR = "stocklocation"
filters = models.CharField( filters = models.CharField(

View File

@ -136,6 +136,10 @@ class PurchaseOrder(Order):
target_date: Expected delivery target date for PurchaseOrder completion (optional) target_date: Expected delivery target date for PurchaseOrder completion (optional)
""" """
@staticmethod
def get_api_url():
return reverse('api-po-list')
OVERDUE_FILTER = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) OVERDUE_FILTER = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
@staticmethod @staticmethod
@ -407,6 +411,10 @@ class SalesOrder(Order):
target_date: Target date for SalesOrder completion (optional) target_date: Target date for SalesOrder completion (optional)
""" """
@staticmethod
def get_api_url():
return reverse('api-so-list')
OVERDUE_FILTER = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) OVERDUE_FILTER = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
@staticmethod @staticmethod
@ -585,6 +593,10 @@ class PurchaseOrderAttachment(InvenTreeAttachment):
Model for storing file attachments against a PurchaseOrder object Model for storing file attachments against a PurchaseOrder object
""" """
@staticmethod
def get_api_url():
return reverse('api-po-attachment-list')
def getSubdir(self): def getSubdir(self):
return os.path.join("po_files", str(self.order.id)) return os.path.join("po_files", str(self.order.id))
@ -596,6 +608,10 @@ class SalesOrderAttachment(InvenTreeAttachment):
Model for storing file attachments against a SalesOrder object Model for storing file attachments against a SalesOrder object
""" """
@staticmethod
def get_api_url():
return reverse('api-so-attachment-list')
def getSubdir(self): def getSubdir(self):
return os.path.join("so_files", str(self.order.id)) return os.path.join("so_files", str(self.order.id))
@ -629,6 +645,11 @@ class PurchaseOrderLineItem(OrderLineItem):
""" """
@staticmethod
def get_api_url():
return reverse('api-po-line-list')
class Meta: class Meta:
unique_together = ( unique_together = (
('order', 'part') ('order', 'part')
@ -712,6 +733,10 @@ class SalesOrderLineItem(OrderLineItem):
sale_price: The unit sale price for this OrderLineItem sale_price: The unit sale price for this OrderLineItem
""" """
@staticmethod
def get_api_url():
return reverse('api-so-line-list')
order = models.ForeignKey(SalesOrder, on_delete=models.CASCADE, related_name='lines', verbose_name=_('Order'), help_text=_('Sales Order')) order = models.ForeignKey(SalesOrder, on_delete=models.CASCADE, related_name='lines', verbose_name=_('Order'), help_text=_('Sales Order'))
part = models.ForeignKey('part.Part', on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, verbose_name=_('Part'), help_text=_('Part'), limit_choices_to={'salable': True}) part = models.ForeignKey('part.Part', on_delete=models.SET_NULL, related_name='sales_order_line_items', null=True, verbose_name=_('Part'), help_text=_('Part'), limit_choices_to={'salable': True})
@ -774,6 +799,10 @@ class SalesOrderAllocation(models.Model):
""" """
@staticmethod
def get_api_url():
return reverse('api-so-allocation-list')
class Meta: class Meta:
unique_together = [ unique_together = [
# Cannot allocate any given StockItem to the same line more than once # Cannot allocate any given StockItem to the same line more than once

View File

@ -75,6 +75,10 @@ class PartCategory(InvenTreeTree):
default_keywords = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Default keywords'), help_text=_('Default keywords for parts in this category')) default_keywords = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Default keywords'), help_text=_('Default keywords for parts in this category'))
@staticmethod
def get_api_url():
return reverse('api-part-category-list')
def get_absolute_url(self): def get_absolute_url(self):
return reverse('category-detail', kwargs={'pk': self.id}) return reverse('category-detail', kwargs={'pk': self.id})
@ -329,6 +333,11 @@ class Part(MPTTModel):
# For legacy reasons the 'variant_of' field is used to indicate the MPTT parent # For legacy reasons the 'variant_of' field is used to indicate the MPTT parent
parent_attr = 'variant_of' parent_attr = 'variant_of'
@staticmethod
def get_api_url():
return reverse('api-part-list')
def get_context_data(self, request, **kwargs): def get_context_data(self, request, **kwargs):
""" """
Return some useful context data about this part for template rendering Return some useful context data about this part for template rendering
@ -1966,6 +1975,10 @@ class PartAttachment(InvenTreeAttachment):
Model for storing file attachments against a Part object Model for storing file attachments against a Part object
""" """
@staticmethod
def get_api_url():
return reverse('api-part-attachment-list')
def getSubdir(self): def getSubdir(self):
return os.path.join("part_files", str(self.part.id)) return os.path.join("part_files", str(self.part.id))
@ -1978,6 +1991,10 @@ class PartSellPriceBreak(common.models.PriceBreak):
Represents a price break for selling this part Represents a price break for selling this part
""" """
@staticmethod
def get_api_url():
return reverse('api-part-sale-price-list')
part = models.ForeignKey( part = models.ForeignKey(
Part, on_delete=models.CASCADE, Part, on_delete=models.CASCADE,
related_name='salepricebreaks', related_name='salepricebreaks',
@ -1994,6 +2011,10 @@ class PartInternalPriceBreak(common.models.PriceBreak):
Represents a price break for internally selling this part Represents a price break for internally selling this part
""" """
@staticmethod
def get_api_url():
return reverse('api-part-internal-price-list')
part = models.ForeignKey( part = models.ForeignKey(
Part, on_delete=models.CASCADE, Part, on_delete=models.CASCADE,
related_name='internalpricebreaks', related_name='internalpricebreaks',
@ -2038,6 +2059,10 @@ class PartTestTemplate(models.Model):
run on the model (refer to the validate_unique function). run on the model (refer to the validate_unique function).
""" """
@staticmethod
def get_api_url():
return reverse('api-part-test-template-list')
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.clean() self.clean()
@ -2136,6 +2161,10 @@ class PartParameterTemplate(models.Model):
units: The units of the Parameter [string] units: The units of the Parameter [string]
""" """
@staticmethod
def get_api_url():
return reverse('api-part-param-template-list')
def __str__(self): def __str__(self):
s = str(self.name) s = str(self.name)
if self.units: if self.units:
@ -2173,6 +2202,10 @@ class PartParameter(models.Model):
data: The data (value) of the Parameter [string] data: The data (value) of the Parameter [string]
""" """
@staticmethod
def get_api_url():
return reverse('api-part-param-list')
def __str__(self): def __str__(self):
# String representation of a PartParameter (used in the admin interface) # String representation of a PartParameter (used in the admin interface)
return "{part} : {param} = {data}{units}".format( return "{part} : {param} = {data}{units}".format(
@ -2264,6 +2297,10 @@ class BomItem(models.Model):
allow_variants: Stock for part variants can be substituted for this BomItem allow_variants: Stock for part variants can be substituted for this BomItem
""" """
@staticmethod
def get_api_url():
return reverse('api-bom-list')
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.clean() self.clean()

View File

@ -4,6 +4,7 @@ JSON serializers for Part app
import imghdr import imghdr
from decimal import Decimal from decimal import Decimal
from django.urls import reverse_lazy
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
@ -187,6 +188,9 @@ class PartSerializer(InvenTreeModelSerializer):
Used when displaying all details of a single component. Used when displaying all details of a single component.
""" """
def get_api_url(self):
return reverse_lazy('api-part-list')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
Custom initialization method for PartSerializer, Custom initialization method for PartSerializer,
@ -305,7 +309,7 @@ class PartSerializer(InvenTreeModelSerializer):
image = InvenTreeImageSerializerField(required=False, allow_null=True) image = InvenTreeImageSerializerField(required=False, allow_null=True)
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
starred = serializers.SerializerMethodField() starred = serializers.BooleanField()
# PrimaryKeyRelated fields (Note: enforcing field type here results in much faster queries, somehow...) # PrimaryKeyRelated fields (Note: enforcing field type here results in much faster queries, somehow...)
category = serializers.PrimaryKeyRelatedField(queryset=PartCategory.objects.all()) category = serializers.PrimaryKeyRelatedField(queryset=PartCategory.objects.all())

View File

@ -11,6 +11,7 @@ import logging
import datetime import datetime
from django.urls import reverse
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError, FieldError from django.core.exceptions import ValidationError, FieldError
@ -307,6 +308,10 @@ class TestReport(ReportTemplateBase):
Render a TestReport against a StockItem object. Render a TestReport against a StockItem object.
""" """
@staticmethod
def get_api_url():
return reverse('api-stockitem-testreport-list')
@classmethod @classmethod
def getSubdir(cls): def getSubdir(cls):
return 'test' return 'test'
@ -361,6 +366,10 @@ class BuildReport(ReportTemplateBase):
Build order / work order report Build order / work order report
""" """
@staticmethod
def get_api_url():
return reverse('api-build-report-list')
@classmethod @classmethod
def getSubdir(cls): def getSubdir(cls):
return 'build' return 'build'
@ -400,6 +409,10 @@ class BillOfMaterialsReport(ReportTemplateBase):
Render a Bill of Materials against a Part object Render a Bill of Materials against a Part object
""" """
@staticmethod
def get_api_url():
return reverse('api-bom-report-list')
@classmethod @classmethod
def getSubdir(cls): def getSubdir(cls):
return 'bom' return 'bom'
@ -430,6 +443,10 @@ class PurchaseOrderReport(ReportTemplateBase):
Render a report against a PurchaseOrder object Render a report against a PurchaseOrder object
""" """
@staticmethod
def get_api_url():
return reverse('api-po-report-list')
@classmethod @classmethod
def getSubdir(cls): def getSubdir(cls):
return 'purchaseorder' return 'purchaseorder'
@ -464,6 +481,10 @@ class SalesOrderReport(ReportTemplateBase):
Render a report against a SalesOrder object Render a report against a SalesOrder object
""" """
@staticmethod
def get_api_url():
return reverse('api-so-report-list')
@classmethod @classmethod
def getSubdir(cls): def getSubdir(cls):
return 'salesorder' return 'salesorder'

View File

@ -1148,7 +1148,7 @@ stock_api_urls = [
url(r'^$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'), url(r'^$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'),
])), ])),
url(r'track/?', StockTrackingList.as_view(), name='api-stock-track'), url(r'track/?', StockTrackingList.as_view(), name='api-stock-tracking-list'),
url(r'^tree/?', StockCategoryTree.as_view(), name='api-stock-tree'), url(r'^tree/?', StockCategoryTree.as_view(), name='api-stock-tree'),

View File

@ -52,6 +52,10 @@ class StockLocation(InvenTreeTree):
Stock locations can be heirarchical as required Stock locations can be heirarchical as required
""" """
@staticmethod
def get_api_url():
return reverse('api-location-list')
owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True, owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True,
verbose_name=_('Owner'), verbose_name=_('Owner'),
help_text=_('Select Owner'), help_text=_('Select Owner'),
@ -161,6 +165,10 @@ class StockItem(MPTTModel):
packaging: Description of how the StockItem is packaged (e.g. "reel", "loose", "tape" etc) packaging: Description of how the StockItem is packaged (e.g. "reel", "loose", "tape" etc)
""" """
@staticmethod
def get_api_url():
return reverse('api-stock-list')
# A Query filter which will be re-used in multiple places to determine if a StockItem is actually "in stock" # A Query filter which will be re-used in multiple places to determine if a StockItem is actually "in stock"
IN_STOCK_FILTER = Q( IN_STOCK_FILTER = Q(
quantity__gt=0, quantity__gt=0,
@ -1608,6 +1616,10 @@ class StockItemAttachment(InvenTreeAttachment):
Model for storing file attachments against a StockItem object. Model for storing file attachments against a StockItem object.
""" """
@staticmethod
def get_api_url():
return reverse('api-stock-attachment-list')
def getSubdir(self): def getSubdir(self):
return os.path.join("stock_files", str(self.stock_item.id)) return os.path.join("stock_files", str(self.stock_item.id))
@ -1639,6 +1651,10 @@ class StockItemTracking(models.Model):
deltas: The changes associated with this history item deltas: The changes associated with this history item
""" """
@staticmethod
def get_api_url():
return reverse('api-stock-tracking-list')
def get_absolute_url(self): def get_absolute_url(self):
return '/stock/track/{pk}'.format(pk=self.id) return '/stock/track/{pk}'.format(pk=self.id)
@ -1697,6 +1713,10 @@ class StockItemTestResult(models.Model):
date: Date the test result was recorded date: Date the test result was recorded
""" """
@staticmethod
def get_api_url():
return reverse('api-stock-test-result-list')
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super().clean() super().clean()

View File

@ -57,7 +57,7 @@
item: {{ item.pk }}, item: {{ item.pk }},
user_detail: true, user_detail: true,
}, },
url: "{% url 'api-stock-track' %}", url: "{% url 'api-stock-tracking-list' %}",
}); });
{% endblock %} {% endblock %}