From 861e30e8d6fa346ac716331dde90a54bdad5f32c Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 26 May 2020 20:04:48 +1000 Subject: [PATCH 1/3] Add a special serializer class for FileField which has a custom to_representation function - This was solving a very subtle bug which will probably only ever apply to a single installation instance - Future me will most likely not remember what this was for or how it works - In any case, there we go - Ref: http://www.cdrf.co/3.9/rest_framework.fields/Field.html (cherry picked from commit 7305094854eef4ff69da6eb62598ef64aadf6cc2) --- InvenTree/InvenTree/serializers.py | 32 ++++++++++++++++++++++++++++++ InvenTree/stock/serializers.py | 3 +++ 2 files changed, 35 insertions(+) diff --git a/InvenTree/InvenTree/serializers.py b/InvenTree/InvenTree/serializers.py index 4ad5d1b87a..6b40b8eb31 100644 --- a/InvenTree/InvenTree/serializers.py +++ b/InvenTree/InvenTree/serializers.py @@ -8,6 +8,9 @@ from __future__ import unicode_literals from rest_framework import serializers +import os + +from django.conf import settings from django.contrib.auth.models import User @@ -50,3 +53,32 @@ class InvenTreeModelSerializer(serializers.ModelSerializer): instance.clean() return data + + +class InvenTreeAttachmentSerializerField(serializers.FileField): + """ + Override the DRF native FileField serializer, + to remove the leading server path. + + For example, the FileField might supply something like: + + http://127.0.0.1:8000/media/foo/bar.jpg + + Whereas we wish to return: + + /media/foo/bar.jpg + + Why? You can't handle the why! + + Actually, if the server process is serving the data at 127.0.0.1, + but a proxy service (e.g. nginx) is then providing DNS lookup to the outside world, + then an attachment which prefixes the "address" of the internal server + will not be accessible from the outside world. + """ + + def to_representation(self, value): + + if not value: + return None + + return os.path.join(str(settings.MEDIA_URL), str(value)) diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 0e63de46f2..b1d30d0e87 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -15,6 +15,7 @@ from django.db.models.functions import Coalesce from company.serializers import SupplierPartSerializer from part.serializers import PartBriefSerializer from InvenTree.serializers import UserSerializerBrief, InvenTreeModelSerializer +from InvenTree.serializers import InvenTreeAttachmentSerializerField class LocationBriefSerializer(InvenTreeModelSerializer): @@ -232,6 +233,8 @@ class StockItemTestResultSerializer(InvenTreeModelSerializer): key = serializers.CharField(read_only=True) + attachment = InvenTreeAttachmentSerializerField() + def __init__(self, *args, **kwargs): user_detail = kwargs.pop('user_detail', False) From 81e38eeb144ad94c8f32bcb883f12e444e21a2c7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 26 May 2020 20:16:10 +1000 Subject: [PATCH 2/3] Add some more custom FileField serializers (cherry picked from commit 7b9ff27baefacc977fef7852e99d8a9bb46a062a) --- InvenTree/order/serializers.py | 6 ++++++ InvenTree/part/serializers.py | 3 +++ InvenTree/stock/serializers.py | 2 ++ 3 files changed, 11 insertions(+) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index c22a637c67..6561d93ddd 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -10,6 +10,8 @@ from rest_framework import serializers from django.db.models import Count from InvenTree.serializers import InvenTreeModelSerializer +from InvenTree.serializers import InvenTreeAttachmentSerializerField + from company.serializers import CompanyBriefSerializer, SupplierPartSerializer from part.serializers import PartBriefSerializer @@ -112,6 +114,8 @@ class POAttachmentSerializer(InvenTreeModelSerializer): Serializers for the PurchaseOrderAttachment model """ + attachment = InvenTreeAttachmentSerializerField() + class Meta: model = PurchaseOrderAttachment @@ -255,6 +259,8 @@ class SOAttachmentSerializer(InvenTreeModelSerializer): Serializers for the SalesOrderAttachment model """ + attachment = InvenTreeAttachmentSerializerField() + class Meta: model = SalesOrderAttachment diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 2cb893b304..e1330cbb56 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -19,6 +19,7 @@ from django.db.models.functions import Coalesce from InvenTree.status_codes import StockStatus, PurchaseOrderStatus, BuildStatus from InvenTree.serializers import InvenTreeModelSerializer +from InvenTree.serializers import InvenTreeAttachmentSerializerField class CategorySerializer(InvenTreeModelSerializer): @@ -46,6 +47,8 @@ class PartAttachmentSerializer(InvenTreeModelSerializer): Serializer for the PartAttachment class """ + attachment = InvenTreeAttachmentSerializerField() + class Meta: model = PartAttachment diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index b1d30d0e87..f41c3f6f89 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -212,6 +212,8 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): user_detail = UserSerializerBrief(source='user', read_only=True) + attachment = InvenTreeAttachmentSerializerField() + class Meta: model = StockItemAttachment From e128410d54c5bcaefeabbba3a7b9a309b0bca752 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 26 May 2020 20:26:37 +1000 Subject: [PATCH 3/3] Update 'required' status for new serializers (cherry picked from commit 2306e29743eb25266c78bec5357d1194e0778c58) --- InvenTree/order/serializers.py | 4 ++-- InvenTree/part/serializers.py | 2 +- InvenTree/stock/serializers.py | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 6561d93ddd..2f87727ced 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -114,7 +114,7 @@ class POAttachmentSerializer(InvenTreeModelSerializer): Serializers for the PurchaseOrderAttachment model """ - attachment = InvenTreeAttachmentSerializerField() + attachment = InvenTreeAttachmentSerializerField(required=True) class Meta: model = PurchaseOrderAttachment @@ -259,7 +259,7 @@ class SOAttachmentSerializer(InvenTreeModelSerializer): Serializers for the SalesOrderAttachment model """ - attachment = InvenTreeAttachmentSerializerField() + attachment = InvenTreeAttachmentSerializerField(required=True) class Meta: model = SalesOrderAttachment diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index e1330cbb56..4efe1fa613 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -47,7 +47,7 @@ class PartAttachmentSerializer(InvenTreeModelSerializer): Serializer for the PartAttachment class """ - attachment = InvenTreeAttachmentSerializerField() + attachment = InvenTreeAttachmentSerializerField(required=True) class Meta: model = PartAttachment diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index f41c3f6f89..e4d602ec11 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -212,7 +212,7 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): user_detail = UserSerializerBrief(source='user', read_only=True) - attachment = InvenTreeAttachmentSerializerField() + attachment = InvenTreeAttachmentSerializerField(required=True) class Meta: model = StockItemAttachment @@ -227,6 +227,12 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): 'user_detail', ] + read_only_fields = [ + 'upload_date', + 'user', + 'user_detail' + ] + class StockItemTestResultSerializer(InvenTreeModelSerializer): """ Serializer for the StockItemTestResult model """ @@ -235,7 +241,7 @@ class StockItemTestResultSerializer(InvenTreeModelSerializer): key = serializers.CharField(read_only=True) - attachment = InvenTreeAttachmentSerializerField() + attachment = InvenTreeAttachmentSerializerField(required=False) def __init__(self, *args, **kwargs): user_detail = kwargs.pop('user_detail', False)