Передача идентификатора связанного поля в конечную точку API в Django REST

Я постараюсь сделать все возможное, чтобы это было легко понять:

[
    {
        "id": 1,
        "data_sheet": "http://127.0.0.1:8000/static/media/store/data_sheets/EN_DS_MVS6300-LV_Datasheet.pdf",
        "module": 3
    },
    {
        "id": 2,
        "data_sheet": "http://127.0.0.1:8000/static/media/store/data_sheets/EN_DS_MVS6300-LV_Datasheet_Pck5SQy.pdf",
        "module": 5
    },
    {
        "id": 3,
        "data_sheet": "http://127.0.0.1:8000/static/media/store/data_sheets/Trina_670Wp_from_Gamechange_abXvA3H.pdf",
        "module": 5
    }
]

В принципе, если я могу перейти к конечной точке, используя id следующим образом: http://127.0.0.1:8000/store/cable_datasheets/1/. Результат будет следующим:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1,
    "data_sheet": "http://127.0.0.1:27038/static/media/store/data_sheets/EN_DS_MVS6300-LV_Datasheet.pdf",
    "module": 3
}

Но я не могу добиться того же самого, используя идентификатор модуля. Например: http://127.0.0.1:8000/store/cable_datasheets/5/ приводит к следующему:

HTTP 404 Not Found
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Not found."
}

модуль оказывается связанным полем, я понятия не имею, как я могу использовать его и передать как часть queryset.

Мой models.py:

class Cable(models.Model):
    id = models.BigAutoField(primary_key=True)

    def __str__(self):
        return f"Cable ({self.tag}, {self.manufacturer}, {self.model})"

    def supports_arch(self, arch):
        return self.architecture[arch] == '1'


class CableDataSheet(models.Model):
    module = models.ForeignKey(Cable, on_delete=models.CASCADE, related_name='data_sheets')
    data_sheet = models.FileField(
        upload_to='store/data_sheets',
        validators=[
            validate_file_size,
            FileExtensionValidator(allowed_extensions=['pdf', 'jpg', 'png'])
        ]
    )

my views.py:

class CableViewSet(ModelViewSet):
    http_method_names = ['get', 'head', 'options']
    serializer_class = CableSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    permission_classes = [IsApplicationOrAdmin]

    def get_queryset(self):
        queryset = Cable.objects.all()
        arch = self.request.query_params.get('arch', False)
        if arch in architectures:
            return queryset.filter(architecture__regex=arch_regex[architectures.index(arch)])
        return queryset

class CableSheets(ModelViewSet):
    http_method_names = ['get', 'head', 'options']
    serializer_class = CableDataSheetSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]


    def get_queryset(self):
        queryset = CableDataSheet.objects.all()
        return queryset

Мои сериализаторы:

class CableDataSheetSerializer(serializers.ModelSerializer):
    module = serializers.SlugRelatedField(
        read_only=True,
        slug_field='id'
    )
    def create(self, validated_data):
        cable_id = self.context['cable_id']
        return CableDataSheet.objects.create(cable_id=cable_id, **validated_data)

    class Meta:
        model = CableDataSheet
        fields = ['id', 'data_sheet', 'module']
    


class CableSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    data_sheets = CableDataSheetSerializer(many=True, read_only=True)

    class Meta:
        model = Cable
        fields = [
            'id','data_sheets'
        ]

Простите, если объяснение получилось слишком длинным, просто пытаюсь донести свой вопрос. Буду признателен, если кто-нибудь сможет помочь

http://127.0.0.1:8000/store/cable_datasheets/5/ запрашивается CableDataSheet с id 5. Учитывая то, что вы предоставили, я предполагаю, что он не существует, отсюда и ошибка 404.

Если вы хотите получить все CableDataSheet, привязанные к модулю с id 5, ваш запрос должен выглядеть как http://127.0.0.1:8000/store/cable_datasheets/?module=5.
Вы должны иметь возможность фильтровать по модулю в методе get_queryset, как вы уже сделали с полем "architecture" (убедитесь, что клиент предоставил номер, иначе django выдаст ошибку)

Вам следует уделить время чтению о конвенциях REST API https://restfulapi.net/

Вернуться на верх