Неполный URL-адрес носителя во вложенных сериализаторах - PullRequest
1 голос
/ 28 апреля 2019

У меня есть приложение django-rest-api с моделями Record, Tag и Weight, где Record и Tag имеют отношение многие ко многим через модель Weight:

# models.py
class Tag(models.Model):
    image = models.ImageField(upload_to='tag_images', null=True, blank=True)

class Record(models.Model):
    file = models.FileField(upload_to='record_files', null=True, blank=True)

class Weight(models.Model):
    record = models.ForeignKey(
        Record,
        related_name='weights',
        on_delete=models.CASCADE
    )
    tag = models.ForeignKey(
        Tag,
        related_name='weights',
        on_delete=models.CASCADE
    )
    value = models.IntegerField()

    class Meta:
        unique_together = ('record', 'tag',)

В моделях Record и Tag есть параметр FileField / ImageField. В моем представлении REST API я хотел бы отобразить подробности записи с полным URL-адресом файла и всеми связанными тегами с полным URL-адресом изображения. Вот так выглядят мои сериализаторы:

# serializers.py
class RecordSerializer(serializers.ModelSerializer):
    tags = serializers.SerializerMethodField()

    class Meta:
        model = Record
        fields = ('id', 'file', 'tags')

    def get_tags(self, obj):
        return TagSerializer(Tag.objects.filter(weights__in=obj.weights.all()), many=True).data

class TagSerializer(serializers.ModelSerializer):

    class Meta:
        model = Tag
        fields = ('id', 'image')

Проблема в том, что когда я вижу подробный вид записи, ее URL файла завершен, но URL изображения тега не являются:

# record detail results
{
    "id": 1,
    "file": "http://127.0.0.1:8080/media/record_files/record00.mp3",
    "tags": [
        {
            "id": 4,
            "image": "/media/tag_images/image04.jpg"
        },
        {
            "id": 10,
            "image": "/media/tag_images/image10.jpg"
        }
    ]
}

В конце концов я обошел проблему, создав отдельный вид списка тегов, и теперь URL-адреса завершены, хотя в файле serializers.py ничего не изменилось.

# record tag list results
[
    {
        "id": 4,
        "image": "http://127.0.0.1:8080/media/tag_images/image04.jpg"
    },
    {
        "id": 10,
        "image": "http://127.0.0.1:8080/media/tag_images/image10.jpg"
    }
]

Полагаю, в любом случае это более чистое решение API для отдыха (хотя я уверен, что мне не понадобятся детали записи и ее теги отдельно). Тем не менее, это все еще вызывает у меня сомнения, почему URL-адреса являются неполными, когда данные являются частью вложенного сериализатора. Это так и должно быть или что я делаю не так?

1 Ответ

1 голос
/ 28 апреля 2019

Похоже, вы, возможно, нашли лучшее решение, но на тот случай, если вам все еще любопытно: проблема с вашей первоначальной попыткой заключалась в том, что вы поместили «вложенный» вызов сериализатора в SerializerMethodField.Обычный способ объявить вложенный сериализатор - инициализировать сериализатор при установке фактического поля.В вашем случае это будет выглядеть примерно так:

class RecordSerializer(serializers.ModelSerializer):
    tags = TagSerializer()

Когда вы делаете это таким образом, TagSerializer может выводить контекст из родительского сериализатора, и частью этого контекста является запрос.Затем он используется в to_representation при вызове build_absolute_uri для генерации полного URL-адреса, на который вы надеялись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...