DjangoRestFramework如何让用户在视图中

问题描述:

我试图做一个朋友饲料,列出我目前的朋友与所有“Beat”对象。我如何访问我的视图中的用户来返回正确的对象?DjangoRestFramework如何让用户在视图中

模型:

class Beat(models.Model): 
    created_at = models.DateTimeField(default=datetime.now) 
    title = models.CharField(max_length=255) 
    description = models.TextField(blank=True, null=True) 
    likes = models.IntegerField(default=0) 
    artist = models.ForeignKey(UserProfile, null=True, blank=True) 
    audio = models.FileField(upload_to="media_files/audio/",null=True, blank=True) 
    beat_cover = models.ImageField(upload_to="media_files/img/",null=True, blank=True); 
    admin_name = models.CharField(max_length=255, blank=True, null=True) 

    class Meta: 
     ordering = ['-created_at'] 

    def __unicode__(self): 
     return unicode(self.admin_name) 



class UserProfile(models.Model): 
    user = models.OneToOneField(User, blank=True, null=True) 
    admin_name = models.CharField(default="beat",max_length=255,blank=True, null=True) 
    profile_pic = models.ImageField(upload_to="media_files/users/") 

    def __unicode__(self): 
     return unicode(self.admin_name) 

串行:

class AllBeatStreamSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Beat 
     fields = ('created_at', 'title', 'audio', 'artist') 
     depth = 1 

视图集:

class FriendsBeatStreamViewSet(viewsets.ModelViewSet): 
    user = self.request.user  
    my_battles = Battle.objects.filter(challenging_beat__artist=user) 
    obj = {} 
    my_beats = Beat.objects.filter(artist=user) 
    related_users = Relationship.objects.filter(from_user=user).values_list('to_user', flat=True).distinct() 
    stream = Beat.objects.filter(artist__in=related_users) 
    stream = list(my_beats) + list(stream) + list(my_battles) 
    queryset = stream 

    serializer_class = AllBeatStreamSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 

直接回答您的问题很简单:覆盖get_queryset而不是将queryset定义为属性,并且您将能够通过self.request.user访问当前用户。

但您的代码示例更复杂。 1)不能将Battle对象与Beat对象混合使用。 2)你的串行器是一个Beat串行器,所以你的queryset必须是Beat实例。

但是,您可以在SQL中使用具有or原因的筛选器将Beat的许多源混合,因此您可以获得所有节拍my_beats OR related_to_me。 Django有一个Q object,可以进行复杂的查找。因此,您可以使用OR运营商|加入两个Q对象。每个Q带有一个代表Beat源的过滤器,如my beatsbeats related to me

您的代码将是这样的:

from django.db.models import Q 

class FriendsBeatStreamViewSet(viewsets.ModelViewSet): 
    serializer_class = AllBeatStreamSerializer 
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,) 

    def get_queryset(self): 
     user = self.request.user 

     my_beats = Q(artist=user) 

     related_users = Relationship.objects \ 
      .filter(from_user=user).values_list('to_user', flat=True).distinct() 
     stream = Q(artist__in=related_users) 

     return Beat.objects.filter(my_beats | stream) 

你应该重写在串行器queryset属性(在那里该逻辑所属)所示:

class AllBeatStreamSerializer(serializers.ModelSerializer): 
    # ... 

    def __init__(self, *args, **kwargs): 
     user = kwargs['context']['request'].user 

     super(AllBeatStreamSerializer, self).__init__(*args, **kwargs) 
     self.fields['parent'].queryset = self.get_request(user) 

    def get_request(self, user): 
     my_battles = Battle.objects.filter(challenging_beat__artist=user) 
     obj = {} 
     my_beats = Beat.objects.filter(artist=user) 
     related_users = Relationship.objects.filter(from_user=user)\ 
          .values_list('to_user', flat=True)\ 
          .distinct() 
     stream = Beat.objects.filter(artist__in=related_users) 
     stream = list(my_beats) + list(stream) + list(my_battles) 
     queryset = stream 

     return queryset