2

Im пытается сделать корм для друзей, в котором перечислены все объекты «Beat», с которыми я сейчас являюсь друзьями. Как я могу получить доступ к пользователю внутри моего представления, чтобы вернуть правильные объекты?DjangoRestFramework Как получить пользователя в viewet

МОДЕЛЬ:

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 

Viewset:

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

ответ

2

Прямой ответ на ваш вопрос прост: переопределите get_queryset вместо определения queryset как атрибута, и вы сможете получить доступ к текущему пользователю по адресу self.request.user.

Но ваш образец кода сложнее. 1) Вы не можете смешать объект Battle с объектами Beat. 2) Ваш сериализатор является сериализатором Beat, поэтому ваш queryset должен быть Beat экземпляров.

Но вы можете смешивать множество источников Beat с использованием фильтра с or причинами в SQL, поэтому вы получаете все удары my_beats OR related_to_me. Django имеет Q object, которые позволяют сложный поиск. Таким образом, вы можете объединить два объекта Q с помощью оператора OR|. Каждый Q с фильтром, который представляет собой источник Beat, например my beats или beats 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) 
0

Вы должны переопределить атрибут 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 
Смежные вопросы