python - 显示嵌套关系的最后一个对象

标签 python django django-rest-framework

我在从两个模型之间的多对多关系返回数据时遇到了问题。我不想显示所有 货币?基于 created_at` 字段,具有与该货币相关的最新Ticker对象的对象。我想知道如何在 json 中创建这样的输出?

期望的输出

[
    {
        "id": 1,
        "name": "Bitcoin",
        "symbol": "BTC",
        "img": "/media/static/img/currencies/bitcoin_uzSOQkH.png",
        "tickers": 
            {
                "rank": 1,
                "price_dkk": "111239.222648",
                "market_cap_dkk": 1861795518438,
                "percent_change_1h": "0.03",
                "percent_change_24h": "2.44",
                "percent_change_7d": "46.80",
                "created_at": "2017-12-12T20:11:49.995851Z"
            }
    }
]

查看

class CurrencyGetView(ProtectedResourceView):
    def get(self, request):
        currencies = CurrencySerializer(Currency.objects.all(), many=True)

        return JsonResponse(currencies.data, safe=False)

序列化器

class TickerSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Ticker
        fields = ('rank', 'price_dkk', 'market_cap_dkk', 'percent_change_1h', 'percent_change_24h', 'percent_change_7d', 'created_at', )


class CurrencySerializer(serializers.HyperlinkedModelSerializer):
    tickers = TickerSerializer(many=True)
    class Meta:
        model = Currency
        fields = ('id', 'name','symbol', 'img', 'tickers',)

模型

class Ticker(models.Model):
    rank = models.IntegerField()
    price_dkk = models.DecimalField(max_digits=20, decimal_places=6)
    market_cap_dkk = models.BigIntegerField()
    percent_change_1h = models.DecimalField(max_digits=4, decimal_places=2)
    percent_change_24h = models.DecimalField(max_digits=4, decimal_places=2)
    percent_change_7d = models.DecimalField(max_digits=4, decimal_places=2)

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = _('Ticker')

    def __str__(self):
        return self.id

class Currency(models.Model):
    symbol = models.CharField(max_length=4, default='BTC', unique=True)
    name = models.CharField(max_length=20, default='Bitcoin', unique=True)
    img = models.ImageField(upload_to = 'static/img/currencies', blank=True)
    is_active = models.BooleanField(default=False)
    tickers = models.ManyToManyField(Ticker)

    class Meta:
        verbose_name_plural = 'currencies'

    def __str__(self):
        return self.name

最佳答案

我觉得这应该在查询级别解决,最好使用 prefetch_related。但是Django can't slice Prefetch objects .无赖。和 Subquery非常缓慢。

我能想到的最佳解决方案是创建一个 SerializerMethodField ,它使用切片数据集调用 TickerSerializer。缺点是 DRF 将为列表中的每个 Currency 对象触发额外的 SQL 查询。

from rest_framework.fields import SerializerMethodField

class CurrencySerializer(serializers.HyperlinkedModelSerializer):
    ticker = SerializerMethodField()

    def get_ticker(self, obj):
        return TickerSerializer(
            instance=obj.tickers.order_by('-created_at')[:1],
            many=True
        ).data

    class Meta:
        model = Currency
        fields = ('id', 'name','symbol', 'img', 'tickers', 'ticker')

关于python - 显示嵌套关系的最后一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47839606/

相关文章:

python - 混淆python类和实例变量

python - 指数小于 1 的 pytorch 数学返回 nan 的

python - Django:越南语的 Slug 工作不正常

python - Django休息框架: Could not resolve URL for hyperlinked relationship using view name "post-detail"

python - 阅读 igraph 中的 Disconected Graph for python

python - Django 可以在没有 FORMS 的情况下上传文件吗?

python - Django TypeError at/render() 得到了意外的关键字参数 'context_instance'

django - Django 中具有模型继承的 RESTful API

python - 如何在 Django REST Framework 中正确嵌套序列化器?

python - django+uwsgi 使用 TimedRotatingFileHandler "overwrites rotated log file"进行日志记录