简体   繁体   中英

Serializing attributes that are not model fields with Django JSON serializer

Not sure what the difference is but I have two snippets of code that i assume should behave the same.

This works:

channels = RpChannels.objects.using('prod').all().filter(userid=id).order_by('-when')
for channel in channels:
    date = channel.t.replace(",","-") if channel.t else "Default"
    name = Playlists.objects.using('prod').get(id=channel.p).description if channel.p else "Default"
    genres = ', '.join(StTag.objects.values_list('tag', flat = True).filter(id__in=channel.g.split(',')).order_by('tag')) if channel.g else "Default"
    when = channel.when if channel.when else "N/A"
    setattr(channel, 'channel', name)
    setattr(channel, 'genres', genres)
    setattr(channel, 'date', date)
    setattr(channel, 'when', when)
    setattr(channel, 'valence', channel.v if channel.v else "Default")
    setattr(channel, 'arousal', channel.a if channel.a else "Default")
context = {'st_user': user,
           'devices': devices,
           'feedback': feedback,
           'stations': stations,
           'channels': channels}
return render(request, 'user.html', context)

This doesn't:

tracks = Songplays.objects.using('prod').all().filter(user=id, when__gt=start, when__lt=end).order_by('-when')
for item in tracks:
    track = Track.objects.get(id=item.trackid)
    artist = Artist.objects.get(id=track.artist_id).name
    title = TrackTitle.objects.get(id=track.id).title
    setattr(item, 'duration', str(datetime.timedelta(seconds=track.duration)) if track.duration else "N/A")
    setattr(item, 'title', title)
    setattr(item, 'artist', artist)
data = serializers.serialize('json', tracks)
return HttpResponse(data, mimetype="application/json")

What i mean by doesn't work is, for example in the first one none of the setattr values exist but they get added to each individual channel and i can access them in my template. However, in the second strip of code duration exists so that modified value gets outputted in my JSON but the other 2 attributes, title and artist, don't exist in the original queryset but unlike with channels they don't get added. Could i have anything to do with the way it's being rendered? If so, why?

Since serializer only uses models field i decided to return a ValuesQuerySet instead of a QuerySet since the former returns a dict. I did this by getting values() instead of all(). Thanks to @PeterDeGlopper for pointing me in the right direction!

# this
tracks = Songplays.objects.using('prod').values().filter(user=id, when__gt=start, when__lt=end).order_by('-when')

#instead of this
tracks = Songplays.objects.using('prod').all().filter(user=id, when__gt=start, when__lt=end).order_by('-when')

Once I had the dict i was able to convert to JSON like this.

import json
data = json.dumps(list(tracks))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM