【发布时间】:2016-08-01 23:11:27
【问题描述】:
有没有办法向使用 Django REST Framework 的 ModelViewSet 的视图的列表 API 调用返回的结果数据添加自定义数据?
我的 ModelViewSet 视图附加到 Items 模型。
除了由 LIST API 调用返回的项目列表之外,我还想查询一个单独的 Seen 模型并与项目一起返回每个项目被看到的次数。
我还想在返回的数据中添加“今日报价”。
我已经搜索了 DRF 文档,但找不到任何关于如何执行此操作的提及。
这是我的代码。 Item 序列化器是:
class ItemSerializer(serializers.ModelSerializer):
username = serializers.SerializerMethodField()
def get_username(self, obj):
"""
Note that query params can be accessed here as follows:
request = self.context['request']
print request.query_params.get['fields']
"""
value = str(obj.owner)
return value
def get_keywords(self, obj):
value = str(obj.keywords)
return value
class Meta:
model = Item
fields = ('id', 'url', 'item_type', 'title', 'credits_applied', 'credits_left', 'credits_gifted', 'username', 'liked', 'disliked')
视图如下所示:
class ItemViewSet(viewsets.ModelViewSet):
queryset = Item.objects.all().order_by('-date_added')
serializer_class = ItemSerializer
# When POSTing (creating) a new item add appropriate User instance to the serializer
def perform_create(self, serializer):
creator = User.objects.get(pk=self.request.data['owner_id'])
serializer.save(owner=creator)
def get_queryset(self):
this_user = self.request.query_params.get('user', None)
restrict_to_items_from_user_id = self.request.query_params.get('from', None)
quantity = self.request.query_params.get('num', 20)
# Use query params to determine what to return
if restrict_to_items_from_user_id is not None:
# API: /api/items/from=<id>
# Return items owned by a specific user. Used by someone to get a list of the items they have added
queryset = Item.objects.filter(owner=restrict_to_items_from_user_id, active=True).order_by('-date_added')[0:int(quantity)]
elif this_user is not None:
# API: /api/items/user=<id>
# Return unseen items for the given user's browse feed
# queryset = Item.objects.all().order_by('-date_added')[0:int(quantity)]
queryset = Item.objects.filter(active=True, credits_left__gt=0).exclude(pk__in=Seen.objects.filter(user_id=this_user).values_list('item_id', flat=True))[0:int(quantity)]
# :TO DO: Add option to list the items a user has liked!
else:
# API: /api/items
# Return items not specific to a particular user (used for testing the app or when user wants to see stuff they have seen before)
queryset = Item.objects.filter(active=True, credits_left__gt=0)[0:int(quantity)]
return queryset
Item 和 Seen 模型是:
class Item(models.Model):
ITEM_TYPES = (
('V', 'Vine'),
('Y', 'YouTube'),
('P', 'Photo'), # Photo is stored by us on a CDN somewhere
('F', 'Flickr'),
('I', 'Instagram'),
('D', 'DeviantArt'),
('5', '500px'),
)
owner = models.ForeignKey(User, on_delete=models.CASCADE) # Id of user who owns the item
title = models.CharField(max_length=60, default='') # URL of where item resides (e.g. Vine or YouTube url)
url = models.CharField(max_length=250, default='', unique=True)
# URL of where item resides (e.g. Vine or YouTube url)
item_type = models.CharField(max_length=1, choices=ITEM_TYPES) # Type of item (e.g. Vine|YoutTube|Instagram|etc.)
keywords = models.ManyToManyField(Keyword, related_name='keywords')
# E.g. Art, Travel, Food, etc.
credits_applied = models.IntegerField(default=10, help_text='Total number of credits applied to this item including any given by VeeU admin')
# Records the total number of credits applied to the Item
credits_left = models.IntegerField(default=10, help_text='The number of credits still remaining to show the item')
# Number of credits left (goes down each time item is viewed
credits_gifted = models.IntegerField(default=0, help_text='The number of credits this item has been gifted by other users')
# Number of credits users have gifted to this item
date_added = models.DateTimeField(auto_now_add=True) # When item was added
liked = models.IntegerField(default=0) # Number of times this item has been liked
disliked = models.IntegerField(default=0) # Number of times this item has been disliked
active = models.BooleanField(default=True, help_text='If you mark this item inactive please say why in the comment field. E.g. "Inapproriate content"')
# True if item is available for showing
comment = models.CharField(max_length=100, blank=True) # Comment to be applied if item is inactive to say why
# Add defs here for model related functions
# This to allow url to be a clickable link
def item_url(self):
return u'<a href="%s">%s</a>' % (self.url, self.url)
item_url.allow_tags = True
def __str__(self):
return '%s: Title: %s, URL: %s' % (self.owner, self.title, self.url)
# Record of which items have been viewed, when, and whether they were liked or not
class Seen(models.Model):
item_seen = models.ForeignKey(Item, on_delete=models.CASCADE) # id of the item that has been seen
who_saw = models.ForeignKey(User, on_delete=models.CASCADE) # id of user who viewed it
date_seen = models.DateTimeField(auto_now_add=True) # When item was viewed
liked = models.BooleanField(help_text='If the item was liked this is set to true')
class Meta:
unique_together = ('item_seen', 'who_saw',)
【问题讨论】:
标签: django django-rest-framework