mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 21:25:42 +00:00 
			
		
		
		
	Schema: Mark nullable fields (#9546)
* Add allow_null to nullable fields * Fix serializer for InfoApi, add nullable flags * Bump api version * Fix incorrectly replaced required tag
This commit is contained in:
		| @@ -229,11 +229,11 @@ class InfoApiSerializer(serializers.Serializer): | |||||||
|  |  | ||||||
|         logo = serializers.CharField() |         logo = serializers.CharField() | ||||||
|         splash = serializers.CharField() |         splash = serializers.CharField() | ||||||
|         login_message = serializers.CharField() |         login_message = serializers.CharField(allow_null=True) | ||||||
|         navbar_message = serializers |         navbar_message = serializers.CharField(allow_null=True) | ||||||
|  |  | ||||||
|     server = serializers.CharField(read_only=True) |     server = serializers.CharField(read_only=True) | ||||||
|     id = serializers.CharField(read_only=True) |     id = serializers.CharField(read_only=True, allow_null=True) | ||||||
|     version = serializers.CharField(read_only=True) |     version = serializers.CharField(read_only=True) | ||||||
|     instance = serializers.CharField(read_only=True) |     instance = serializers.CharField(read_only=True) | ||||||
|     apiVersion = serializers.IntegerField(read_only=True)  # noqa: N815 |     apiVersion = serializers.IntegerField(read_only=True)  # noqa: N815 | ||||||
| @@ -246,15 +246,13 @@ class InfoApiSerializer(serializers.Serializer): | |||||||
|     email_configured = serializers.BooleanField(read_only=True) |     email_configured = serializers.BooleanField(read_only=True) | ||||||
|     debug_mode = serializers.BooleanField(read_only=True) |     debug_mode = serializers.BooleanField(read_only=True) | ||||||
|     docker_mode = serializers.BooleanField(read_only=True) |     docker_mode = serializers.BooleanField(read_only=True) | ||||||
|     default_locale = serializers.ChoiceField( |     default_locale = serializers.CharField(read_only=True) | ||||||
|         choices=settings.LOCALE_CODES, read_only=True |  | ||||||
|     ) |  | ||||||
|     customize = CustomizeSerializer(read_only=True) |     customize = CustomizeSerializer(read_only=True) | ||||||
|     system_health = serializers.BooleanField(read_only=True) |     system_health = serializers.BooleanField(read_only=True) | ||||||
|     database = serializers.CharField(read_only=True) |     database = serializers.CharField(read_only=True) | ||||||
|     platform = serializers.CharField(read_only=True) |     platform = serializers.CharField(read_only=True) | ||||||
|     installer = serializers.CharField(read_only=True) |     installer = serializers.CharField(read_only=True) | ||||||
|     target = serializers.CharField(read_only=True) |     target = serializers.CharField(read_only=True, allow_null=True) | ||||||
|     django_admin = serializers.CharField(read_only=True) |     django_admin = serializers.CharField(read_only=True) | ||||||
|     settings = SettingsSerializer(read_only=True, many=False) |     settings = SettingsSerializer(read_only=True, many=False) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,13 +1,16 @@ | |||||||
| """InvenTree API version information.""" | """InvenTree API version information.""" | ||||||
|  |  | ||||||
| # InvenTree API version | # InvenTree API version | ||||||
| INVENTREE_API_VERSION = 339 | INVENTREE_API_VERSION = 340 | ||||||
|  |  | ||||||
| """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" | """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" | ||||||
|  |  | ||||||
|  |  | ||||||
| INVENTREE_API_TEXT = """ | INVENTREE_API_TEXT = """ | ||||||
|  |  | ||||||
|  | v340 -> 2025-04-15 : https://github.com/inventree/InvenTree/pull/9546 | ||||||
|  |     - Add nullable to various fields to make them not required | ||||||
|  |  | ||||||
| v339 -> 2025-04-15 : https://github.com/inventree/InvenTree/pull/9283 | v339 -> 2025-04-15 : https://github.com/inventree/InvenTree/pull/9283 | ||||||
|     - Remove need for source in /plugins/ui/features |     - Remove need for source in /plugins/ui/features | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1431,7 +1431,12 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali | |||||||
|         pricing=False, |         pricing=False, | ||||||
|     ) |     ) | ||||||
|     build_detail = BuildSerializer( |     build_detail = BuildSerializer( | ||||||
|         label=_('Build'), source='build', part_detail=False, many=False, read_only=True |         label=_('Build'), | ||||||
|  |         source='build', | ||||||
|  |         part_detail=False, | ||||||
|  |         many=False, | ||||||
|  |         read_only=True, | ||||||
|  |         allow_null=True, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Annotated (calculated) fields |     # Annotated (calculated) fields | ||||||
|   | |||||||
| @@ -812,6 +812,4 @@ class DataOutputSerializer(InvenTreeModelSerializer): | |||||||
|  |  | ||||||
|     user_detail = UserSerializer(source='user', read_only=True, many=False) |     user_detail = UserSerializer(source='user', read_only=True, many=False) | ||||||
|  |  | ||||||
|     output = InvenTreeAttachmentSerializerField( |     output = InvenTreeAttachmentSerializerField(allow_null=True, read_only=True) | ||||||
|         required=False, allow_null=True, read_only=True |  | ||||||
|     ) |  | ||||||
|   | |||||||
| @@ -169,7 +169,7 @@ class CompanySerializer( | |||||||
|         read_only=True, |         read_only=True, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     primary_address = AddressSerializer(required=False, allow_null=True, read_only=True) |     primary_address = AddressSerializer(allow_null=True, read_only=True) | ||||||
|  |  | ||||||
|     image = InvenTreeImageSerializerField(required=False, allow_null=True) |     image = InvenTreeImageSerializerField(required=False, allow_null=True) | ||||||
|  |  | ||||||
| @@ -463,7 +463,7 @@ class SupplierPartSerializer( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     MPN = serializers.CharField( |     MPN = serializers.CharField( | ||||||
|         source='manufacturer_part.MPN', read_only=True, label=_('MPN') |         source='manufacturer_part.MPN', read_only=True, allow_null=True, label=_('MPN') | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Date fields |     # Date fields | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ class DataImporterModelSerializer(serializers.Serializer): | |||||||
|  |  | ||||||
|     serializer = serializers.CharField(read_only=True) |     serializer = serializers.CharField(read_only=True) | ||||||
|     model_type = serializers.CharField(read_only=True) |     model_type = serializers.CharField(read_only=True) | ||||||
|     api_url = serializers.URLField(read_only=True) |     api_url = serializers.URLField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|  |  | ||||||
| class DataImporterModelList(APIView): | class DataImporterModelList(APIView): | ||||||
|   | |||||||
| @@ -112,11 +112,13 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria | |||||||
|     import_exclude_fields = ['notes', 'duplicate'] |     import_exclude_fields = ['notes', 'duplicate'] | ||||||
|  |  | ||||||
|     # Number of line items in this order |     # Number of line items in this order | ||||||
|     line_items = serializers.IntegerField(read_only=True, label=_('Line Items')) |     line_items = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Line Items') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     # Number of completed line items (this is an annotated field) |     # Number of completed line items (this is an annotated field) | ||||||
|     completed_lines = serializers.IntegerField( |     completed_lines = serializers.IntegerField( | ||||||
|         read_only=True, label=_('Completed Lines') |         read_only=True, allow_null=True, label=_('Completed Lines') | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Human-readable status text (read-only) |     # Human-readable status text (read-only) | ||||||
| @@ -156,7 +158,7 @@ class AbstractOrderSerializer(DataImportExportSerializerMixin, serializers.Seria | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Boolean field indicating if this order is overdue (Note: must be annotated) |     # Boolean field indicating if this order is overdue (Note: must be annotated) | ||||||
|     overdue = serializers.BooleanField(required=False, read_only=True) |     overdue = serializers.BooleanField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|     barcode_hash = serializers.CharField(read_only=True) |     barcode_hash = serializers.CharField(read_only=True) | ||||||
|  |  | ||||||
| @@ -609,7 +611,7 @@ class PurchaseOrderLineItemSerializer( | |||||||
|  |  | ||||||
|     received = serializers.FloatField(default=0, read_only=True) |     received = serializers.FloatField(default=0, read_only=True) | ||||||
|  |  | ||||||
|     overdue = serializers.BooleanField(required=False, read_only=True) |     overdue = serializers.BooleanField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|     total_price = serializers.FloatField(read_only=True) |     total_price = serializers.FloatField(read_only=True) | ||||||
|  |  | ||||||
| @@ -632,7 +634,7 @@ class PurchaseOrderLineItemSerializer( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     destination_detail = stock.serializers.LocationBriefSerializer( |     destination_detail = stock.serializers.LocationBriefSerializer( | ||||||
|         source='get_destination', read_only=True |         source='get_destination', read_only=True, allow_null=True | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     purchase_price_currency = InvenTreeCurrencySerializer( |     purchase_price_currency = InvenTreeCurrencySerializer( | ||||||
| @@ -652,14 +654,22 @@ class PurchaseOrderLineItemSerializer( | |||||||
|         write_only=True, |         write_only=True, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     sku = serializers.CharField(source='part.SKU', read_only=True, label=_('SKU')) |     sku = serializers.CharField( | ||||||
|  |         source='part.SKU', read_only=True, allow_null=True, label=_('SKU') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     mpn = serializers.CharField( |     mpn = serializers.CharField( | ||||||
|         source='part.manufacturer_part.MPN', read_only=True, label=_('MPN') |         source='part.manufacturer_part.MPN', | ||||||
|  |         read_only=True, | ||||||
|  |         allow_null=True, | ||||||
|  |         label=_('MPN'), | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     ipn = serializers.CharField( |     ipn = serializers.CharField( | ||||||
|         source='part.part.IPN', read_only=True, label=_('Internal Part Number') |         source='part.part.IPN', | ||||||
|  |         read_only=True, | ||||||
|  |         allow_null=True, | ||||||
|  |         label=_('Internal Part Number'), | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     internal_part = serializers.PrimaryKeyRelatedField( |     internal_part = serializers.PrimaryKeyRelatedField( | ||||||
| @@ -1078,10 +1088,12 @@ class SalesOrderSerializer( | |||||||
|         source='customer', many=False, read_only=True, allow_null=True |         source='customer', many=False, read_only=True, allow_null=True | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     shipments_count = serializers.IntegerField(read_only=True, label=_('Shipments')) |     shipments_count = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Shipments') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     completed_shipments_count = serializers.IntegerField( |     completed_shipments_count = serializers.IntegerField( | ||||||
|         read_only=True, label=_('Completed Shipments') |         read_only=True, allow_null=True, label=_('Completed Shipments') | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1253,7 +1265,7 @@ class SalesOrderLineItemSerializer( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Annotated fields |     # Annotated fields | ||||||
|     overdue = serializers.BooleanField(required=False, read_only=True) |     overdue = serializers.BooleanField(read_only=True, allow_null=True) | ||||||
|     available_stock = serializers.FloatField(read_only=True) |     available_stock = serializers.FloatField(read_only=True) | ||||||
|     available_variant_stock = serializers.FloatField(read_only=True) |     available_variant_stock = serializers.FloatField(read_only=True) | ||||||
|     on_order = serializers.FloatField(label=_('On Order'), read_only=True) |     on_order = serializers.FloatField(label=_('On Order'), read_only=True) | ||||||
| @@ -1316,7 +1328,7 @@ class SalesOrderShipmentSerializer(NotesFieldMixin, InvenTreeModelSerializer): | |||||||
|         return queryset |         return queryset | ||||||
|  |  | ||||||
|     allocated_items = serializers.IntegerField( |     allocated_items = serializers.IntegerField( | ||||||
|         read_only=True, label=_('Allocated Items') |         read_only=True, allow_null=True, label=_('Allocated Items') | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     order_detail = SalesOrderSerializer( |     order_detail = SalesOrderSerializer( | ||||||
| @@ -1389,7 +1401,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer): | |||||||
|     order = serializers.PrimaryKeyRelatedField( |     order = serializers.PrimaryKeyRelatedField( | ||||||
|         source='line.order', many=False, read_only=True |         source='line.order', many=False, read_only=True | ||||||
|     ) |     ) | ||||||
|     serial = serializers.CharField(source='get_serial', read_only=True) |     serial = serializers.CharField(source='get_serial', read_only=True, allow_null=True) | ||||||
|     quantity = serializers.FloatField(read_only=False) |     quantity = serializers.FloatField(read_only=False) | ||||||
|     location = serializers.PrimaryKeyRelatedField( |     location = serializers.PrimaryKeyRelatedField( | ||||||
|         source='item.location', many=False, read_only=True |         source='item.location', many=False, read_only=True | ||||||
|   | |||||||
| @@ -126,9 +126,13 @@ class CategorySerializer( | |||||||
|         help_text=_('Parent part category'), |         help_text=_('Parent part category'), | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     part_count = serializers.IntegerField(read_only=True, label=_('Parts')) |     part_count = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Parts') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     subcategories = serializers.IntegerField(read_only=True, label=_('Subcategories')) |     subcategories = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Subcategories') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     level = serializers.IntegerField(read_only=True) |     level = serializers.IntegerField(read_only=True) | ||||||
|  |  | ||||||
| @@ -149,7 +153,7 @@ class CategorySerializer( | |||||||
|         max_length=100, |         max_length=100, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     parent_default_location = serializers.IntegerField(read_only=True) |     parent_default_location = serializers.IntegerField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|  |  | ||||||
| class CategoryTree(InvenTree.serializers.InvenTreeModelSerializer): | class CategoryTree(InvenTree.serializers.InvenTreeModelSerializer): | ||||||
| @@ -335,6 +339,7 @@ class PartParameterTemplateSerializer( | |||||||
|  |  | ||||||
|     parts = serializers.IntegerField( |     parts = serializers.IntegerField( | ||||||
|         read_only=True, |         read_only=True, | ||||||
|  |         allow_null=True, | ||||||
|         label=_('Parts'), |         label=_('Parts'), | ||||||
|         help_text=_('Number of parts using this template'), |         help_text=_('Number of parts using this template'), | ||||||
|     ) |     ) | ||||||
| @@ -396,7 +401,9 @@ class PartBriefSerializer(InvenTree.serializers.InvenTreeModelSerializer): | |||||||
|         read_only=True, allow_null=True |         read_only=True, allow_null=True | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     image = InvenTree.serializers.InvenTreeImageSerializerField(read_only=True) |     image = InvenTree.serializers.InvenTreeImageSerializerField( | ||||||
|  |         read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|     thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) |     thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) | ||||||
|  |  | ||||||
|     IPN = serializers.CharField( |     IPN = serializers.CharField( | ||||||
| @@ -924,25 +931,47 @@ class PartSerializer( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Annotated fields |     # Annotated fields | ||||||
|     allocated_to_build_orders = serializers.FloatField(read_only=True) |     allocated_to_build_orders = serializers.FloatField(read_only=True, allow_null=True) | ||||||
|     allocated_to_sales_orders = serializers.FloatField(read_only=True) |     allocated_to_sales_orders = serializers.FloatField(read_only=True, allow_null=True) | ||||||
|     building = serializers.FloatField(read_only=True, label=_('Building')) |     building = serializers.FloatField( | ||||||
|     in_stock = serializers.FloatField(read_only=True, label=_('In Stock')) |         read_only=True, allow_null=True, label=_('Building') | ||||||
|     ordering = serializers.FloatField(read_only=True, label=_('On Order')) |     ) | ||||||
|     required_for_build_orders = serializers.IntegerField(read_only=True) |     in_stock = serializers.FloatField( | ||||||
|     required_for_sales_orders = serializers.IntegerField(read_only=True) |         read_only=True, allow_null=True, label=_('In Stock') | ||||||
|     stock_item_count = serializers.IntegerField(read_only=True, label=_('Stock Items')) |     ) | ||||||
|     revision_count = serializers.IntegerField(read_only=True, label=_('Revisions')) |     ordering = serializers.FloatField( | ||||||
|     suppliers = serializers.IntegerField(read_only=True, label=_('Suppliers')) |         read_only=True, allow_null=True, label=_('On Order') | ||||||
|     total_in_stock = serializers.FloatField(read_only=True, label=_('Total Stock')) |     ) | ||||||
|     external_stock = serializers.FloatField(read_only=True, label=_('External Stock')) |     required_for_build_orders = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |     required_for_sales_orders = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |     stock_item_count = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Stock Items') | ||||||
|  |     ) | ||||||
|  |     revision_count = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Revisions') | ||||||
|  |     ) | ||||||
|  |     suppliers = serializers.IntegerField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Suppliers') | ||||||
|  |     ) | ||||||
|  |     total_in_stock = serializers.FloatField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Total Stock') | ||||||
|  |     ) | ||||||
|  |     external_stock = serializers.FloatField( | ||||||
|  |         read_only=True, allow_null=True, label=_('External Stock') | ||||||
|  |     ) | ||||||
|     unallocated_stock = serializers.FloatField( |     unallocated_stock = serializers.FloatField( | ||||||
|         read_only=True, label=_('Unallocated Stock') |         read_only=True, allow_null=True, label=_('Unallocated Stock') | ||||||
|     ) |     ) | ||||||
|     category_default_location = serializers.IntegerField( |     category_default_location = serializers.IntegerField( | ||||||
|         read_only=True, allow_null=True |         read_only=True, allow_null=True | ||||||
|     ) |     ) | ||||||
|     variant_stock = serializers.FloatField(read_only=True, label=_('Variant Stock')) |     variant_stock = serializers.FloatField( | ||||||
|  |         read_only=True, allow_null=True, label=_('Variant Stock') | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     minimum_stock = serializers.FloatField( |     minimum_stock = serializers.FloatField( | ||||||
|         required=False, label=_('Minimum Stock'), default=0 |         required=False, label=_('Minimum Stock'), default=0 | ||||||
| @@ -1657,11 +1686,17 @@ class BomItemSerializer( | |||||||
|         allow_null=True, |         allow_null=True, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     on_order = serializers.FloatField(label=_('On Order'), read_only=True) |     on_order = serializers.FloatField( | ||||||
|  |         label=_('On Order'), read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     building = serializers.FloatField(label=_('In Production'), read_only=True) |     building = serializers.FloatField( | ||||||
|  |         label=_('In Production'), read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     can_build = serializers.FloatField(label=_('Can Build'), read_only=True) |     can_build = serializers.FloatField( | ||||||
|  |         label=_('Can Build'), read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     # Cached pricing fields |     # Cached pricing fields | ||||||
|     pricing_min = InvenTree.serializers.InvenTreeMoneySerializer( |     pricing_min = InvenTree.serializers.InvenTreeMoneySerializer( | ||||||
| @@ -1684,12 +1719,14 @@ class BomItemSerializer( | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     # Annotated fields for available stock |     # Annotated fields for available stock | ||||||
|     available_stock = serializers.FloatField(label=_('Available Stock'), read_only=True) |     available_stock = serializers.FloatField( | ||||||
|  |         label=_('Available Stock'), read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     available_substitute_stock = serializers.FloatField(read_only=True) |     available_substitute_stock = serializers.FloatField(read_only=True, allow_null=True) | ||||||
|     available_variant_stock = serializers.FloatField(read_only=True) |     available_variant_stock = serializers.FloatField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|     external_stock = serializers.FloatField(read_only=True) |     external_stock = serializers.FloatField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def annotate_queryset(queryset): |     def annotate_queryset(queryset): | ||||||
|   | |||||||
| @@ -655,20 +655,20 @@ class StockItemSerializer( | |||||||
|  |  | ||||||
|     # Annotated fields |     # Annotated fields | ||||||
|     allocated = serializers.FloatField( |     allocated = serializers.FloatField( | ||||||
|         required=False, read_only=True, label=_('Allocated Quantity') |         read_only=True, allow_null=True, label=_('Allocated Quantity') | ||||||
|     ) |     ) | ||||||
|     expired = serializers.BooleanField( |     expired = serializers.BooleanField( | ||||||
|         required=False, read_only=True, label=_('Expired') |         read_only=True, allow_null=True, label=_('Expired') | ||||||
|     ) |     ) | ||||||
|     installed_items = serializers.IntegerField( |     installed_items = serializers.IntegerField( | ||||||
|         read_only=True, required=False, label=_('Installed Items') |         read_only=True, allow_null=True, label=_('Installed Items') | ||||||
|     ) |     ) | ||||||
|     child_items = serializers.IntegerField( |     child_items = serializers.IntegerField( | ||||||
|         read_only=True, required=False, label=_('Child Items') |         read_only=True, allow_null=True, label=_('Child Items') | ||||||
|     ) |     ) | ||||||
|     stale = serializers.BooleanField(required=False, read_only=True, label=_('Stale')) |     stale = serializers.BooleanField(read_only=True, allow_null=True, label=_('Stale')) | ||||||
|     tracking_items = serializers.IntegerField( |     tracking_items = serializers.IntegerField( | ||||||
|         read_only=True, required=False, label=_('Tracking Items') |         read_only=True, allow_null=True, label=_('Tracking Items') | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     purchase_price = InvenTree.serializers.InvenTreeMoneySerializer( |     purchase_price = InvenTree.serializers.InvenTreeMoneySerializer( | ||||||
| @@ -1161,7 +1161,7 @@ class StockLocationTypeSerializer(InvenTree.serializers.InvenTreeModelSerializer | |||||||
|  |  | ||||||
|         read_only_fields = ['location_count'] |         read_only_fields = ['location_count'] | ||||||
|  |  | ||||||
|     location_count = serializers.IntegerField(read_only=True) |     location_count = serializers.IntegerField(read_only=True, allow_null=True) | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def annotate_queryset(queryset): |     def annotate_queryset(queryset): | ||||||
| @@ -1273,7 +1273,7 @@ class LocationSerializer( | |||||||
|  |  | ||||||
|     # Detail for location type |     # Detail for location type | ||||||
|     location_type_detail = StockLocationTypeSerializer( |     location_type_detail = StockLocationTypeSerializer( | ||||||
|         source='location_type', read_only=True, many=False |         source='location_type', read_only=True, allow_null=True, many=False | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -283,9 +283,13 @@ class GroupSerializer(InvenTreeModelSerializer): | |||||||
|         """Return a list of permissions associated with the group.""" |         """Return a list of permissions associated with the group.""" | ||||||
|         return generate_permission_dict(group.permissions.all()) |         return generate_permission_dict(group.permissions.all()) | ||||||
|  |  | ||||||
|     roles = RuleSetSerializer(source='rule_sets', many=True, read_only=True) |     roles = RuleSetSerializer( | ||||||
|  |         source='rule_sets', many=True, read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     users = UserSerializer(source='user_set', many=True, read_only=True) |     users = UserSerializer( | ||||||
|  |         source='user_set', many=True, read_only=True, allow_null=True | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| class ExtendedUserSerializer(UserSerializer): | class ExtendedUserSerializer(UserSerializer): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user