Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DjangoRestFramework how to get user in viewset

Im trying to make a friends feed that lists all "Beat" objects that i am currently friends with. How can i access user inside of my viewset to return the correct objects?

MODELS:

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)

SERIALIZERS:

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,)
like image 790
ryan Avatar asked Jan 23 '16 20:01

ryan


1 Answers

The direct answer to your question is simple: Override get_queryset instead of defining queryset as an attribute, and you'll be able to access the current user on self.request.user.

But your code sample is more complex. 1) You can't mix Battle object with Beat objects. 2) Your serializer is a Beat serializer, so your queryset must be of Beat instances.

But you can mix many sources of Beat using a filter with or causes in SQL, so you get all beats that are my_beats OR related_to_me. Django has a Q object that allow complex lookups. So you can join two Q objects using the OR operator |. Each Q with a filter that represents a Beat source, like my beats or beats related to me.

Your code will be something like this:

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)
like image 117
Fernando Macedo Avatar answered Sep 20 '22 01:09

Fernando Macedo