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/order/serializers.py b/InvenTree/order/serializers.py index c22a637c67..2f87727ced 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(required=True) + class Meta: model = PurchaseOrderAttachment @@ -255,6 +259,8 @@ class SOAttachmentSerializer(InvenTreeModelSerializer): Serializers for the SalesOrderAttachment model """ + attachment = InvenTreeAttachmentSerializerField(required=True) + class Meta: model = SalesOrderAttachment diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 2cb893b304..4efe1fa613 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(required=True) + class Meta: model = PartAttachment diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 0e63de46f2..e4d602ec11 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): @@ -211,6 +212,8 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): user_detail = UserSerializerBrief(source='user', read_only=True) + attachment = InvenTreeAttachmentSerializerField(required=True) + class Meta: model = StockItemAttachment @@ -224,6 +227,12 @@ class StockItemAttachmentSerializer(InvenTreeModelSerializer): 'user_detail', ] + read_only_fields = [ + 'upload_date', + 'user', + 'user_detail' + ] + class StockItemTestResultSerializer(InvenTreeModelSerializer): """ Serializer for the StockItemTestResult model """ @@ -232,6 +241,8 @@ class StockItemTestResultSerializer(InvenTreeModelSerializer): key = serializers.CharField(read_only=True) + attachment = InvenTreeAttachmentSerializerField(required=False) + def __init__(self, *args, **kwargs): user_detail = kwargs.pop('user_detail', False)