首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >传递给我的ListSerializer的to_representation函数的“实例”是什么?

传递给我的ListSerializer的to_representation函数的“实例”是什么?
EN

Stack Overflow用户
提问于 2020-04-01 03:35:56
回答 1查看 451关注 0票数 1

这个项目的目标是创建一个API,每小时刷新与最新的投注赔率的游戏,我将从互联网上抓取每小时。返回的JSON的目标结构将是每个游戏作为父对象,嵌套子对象将是更新日期之前抓取的每个date的前1个记录。我的理解是,实现这一点的最好方法是修改ListSerializer中的to_representation函数以返回适当的查询集。

因为我需要父元素的game_id来获取相应游戏的子元素,所以我尝试从传递的数据中提取game_id。问题是,当我通过异常看到该行包含的内容时,它看起来是正确填充的,但当我让完整代码运行时,我得到了一个列表索引超出范围的异常。

对于ex。

代码语言:javascript
复制
class OddsMakerListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        game = data.all()[0].game_id

        #if I put this here it evaluates to 1 which should run the raw sql below correctly
        raise Exception(game) 
        data = OddsMaker.objects.filter(odds_id__in = RawSQL(''' SELECT o.odds_id
                                                                    FROM gamesbackend_oddsmaker o
                                                              INNER JOIN (
                                                                          SELECT game_id
                                                                               , oddsmaker
                                                                               , max(updated_datetime)            as last_updated
                                                                            FROM gamesbackend_oddsmaker
                                                                           WHERE game_id = %s
                                                                        GROUP BY game_id
                                                                               , oddsmaker
                                                                         ) l on o.game_id = l.game_id
                                                                            and o.oddsmaker = l.oddsmaker
                                                                            and o.updated_datetime = l.last_updated
                                                              ''', [game]))
        #if I put this here the data appears to be populated correctly and contain the right data
        raise Exception(data)
        data = [game for game in data]
        return data

现在,如果我删除这些raise异常,我得到的列表索引超出了范围。我最初的想法是,还有一些东西依赖于以列表形式返回的“数据”,所以我创建了列表理解片段,但这并不能解决问题。

所以,我的问题是: 1)有没有更简单的方法来完成我要做的事情?我没有使用postgres后端,所以我不能使用截然不同的。2)如果不是,我不清楚传入的是什么实例,也不清楚预计会返回什么。我查阅了文档,它看起来需要一个字典,这可能是问题的一部分,但错误消息再次引用了一个列表。https://www.django-rest-framework.org/api-guide/serializers/#overriding-serialization-and-deserialization-behavior

我很感谢任何提前了解这里发生的事情的帮助。

编辑:其余的序列化程序:

代码语言:javascript
复制
class OddsMakerSerializer(serializers.ModelSerializer):
    class Meta:
        list_serializer_class = OddsMakerListSerializer
        model = OddsMaker
        fields = ('odds_id','game_id','oddsmaker','home_ml',
                  'away_ml','home_spread','home_spread_odds',
                  'away_spread_odds','total','total_over_odds',
                  'total_under_odds','updated_datetime')


class GameSerializer(serializers.ModelSerializer):
    oddsmaker_set = OddsMakerSerializer(many=True, read_only=True)

    class Meta:
        model = Game
        fields = ('game_id','date','sport', 'home_team',
                  'away_team','home_score', 'away_score',
                  'home_win','away_win', 'game_completed',
                  'oddsmaker_set')

models.py:

代码语言:javascript
复制
class Game(models.Model):
    game_id = models.AutoField(primary_key=True)
    date = models.DateTimeField(null=True)
    sport=models.CharField(max_length=256, null=True)
    home_team = models.CharField(max_length=256, null=True)
    away_team = models.CharField(max_length=256, null=True)
    home_score = models.IntegerField(default=0, null=True)
    away_score = models.IntegerField(default=0, null=True)
    home_win = models.BooleanField(default=0, null=True)
    away_win = models.BooleanField(default=0, null=True)
    game_completed = models.BooleanField(default=0, null=True)

class OddsMaker(models.Model):
    odds_id = models.AutoField(primary_key=True)
    game = models.ForeignKey('Game', on_delete = models.CASCADE)
    oddsmaker = models.CharField(max_length=256)
    home_ml = models.IntegerField(default=999999)
    away_ml = models.IntegerField(default=999999)
    home_spread = models.FloatField(default=999)
    home_spread_odds = models.IntegerField(default=9999)
    away_spread_odds = models.IntegerField(default=9999)
    total = models.FloatField(default=999)
    total_over_odds = models.IntegerField(default=999)
    total_under_odds = models.IntegerField(default=999)
    updated_datetime = models.DateTimeField(auto_now=True)

views.py:

代码语言:javascript
复制
class GameView(viewsets.ModelViewSet):      
  queryset = Game.objects.all()             
  serializer_class = GameSerializer  

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-01 04:07:38

要回答标题中的问题:

传递给Serializer.to_representation()instance是初始化序列化程序时传递的实例

代码语言:javascript
复制
queryset = MyModel.objects.all()
Serializer(queryset, many=True)

instance = MyModel.objects.all().first()
Serializer(data)

通常,您不必从ListSerializer本身继承。你可以从BaseSerializer继承,只要你在初始化时传递many=True,它就会自动‘变成aListSerializer`。You can see this in action here

来回答你的问题

代码语言:javascript
复制
from django.db.models import Max
class OddsMakerListSerializer(serializers.ListSerializer):
    def to_representation(self, data): # data passed is a queryset of oddsmaker                 
        # Do your filtering here
        latest_date = data.aggregate(
            latest_date=Max('updated_datetime')
        ).get('latest_date').date()   
        latest_records = data.filter(
            updated_date_time__year=latest_date.year,
            updated_date_time__month=latest_date.month,
            updated_date_time__day=latest_date.day
        )
        return super().to_representation(latest_records)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60958512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档