2016-04-11 13 views
0

Django REST FrameworkのModelViewSetを使用するビューへのリストAPI呼び出しによって返された結果データにカスタムデータを追加する方法はありますか?Django RESTフレームワークのModelViewSetによって返されたリストにデータを追加

My ModelViewSetビューはItemsモデルに関連付けられています。

LIST API呼び出しによって返される項目のリストに加えて、私は別個のSeenモデルを照会し、各項目が見られた回数を項目とともに返したいと思う。

また、返されたデータに「Quote of the day」を追加します。

私はDRFのドキュメントを検索しましたが、これを行う方法の説明は見つかりませんでした。

ここに私のコードです。アイテムのシリアライザは、次のとおりです。

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

項目と見モデルは以下のとおりです。

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',)

答えて

1

あなたが定期的に応答に新しいデータを添付したい場合は、あなたがそれを行うことができます。

class ItemViewSet(viewsets.ModelViewSet): 
    ... 

    def list(self, request, *args, **kwargs): 
     custom_data = { 
      'list_of_items': ItemSerializer(self.get_queryset(),many=true).data # this is the default result you are getting today 
     } 
     custom_data.update({ 
      'quote_of_the_day': # code to compute Quote of the day 
      'number_of_times': # code to compute number of times 
     }) 
     return Response(custom_data) 
    ... 

ものの、そしてあなたのコメントから判断:「回数各項目を」と語った。時間数は各アイテムの新しいプロパティのように見えますので、次のようにすることもできます:

class ItemViewSet(viewsets.ModelViewSet): 
    ... 

    def list(self, request, *args, **kwargs): 
     custom_data = { 
     'list_of_items': ItemSerializer(self.get_queryset(), many=true).data # this is the default result you are getting today 
     } 
     custom_data.update({ 
      'quote_of_the_day': # code to compute Quote of the day 
     }) 
     return Response(custom_data) 
... 

class ItemSerializer(serializers.ModelSerializer): 
    ... 
    number_of_times = serializers.SerializerMethodField() 
    ... 

    def get_number_of_times(self): 
     # compute and return the number of times the Item has been seen. 
    ... 
+0

どのサンプルコードでも私を指摘できますか?私はこれを行う方法を解決することはできません。私は既に標準的なリスト結果のシリアライザを持っています。 –

+0

関連モデルとシリアライザを提供してもらえますか?私はカスタマイズのお手伝いをすることができます – trinchet

+0

ありがとう@trinchet質問に自分のコードを追加しました。うまくいけば、それは今より意味をなさない! –

関連する問題