DjangoRestFramework如何在viewset中获取用户

时间:2016-01-23 20:53:10

标签: python django django-models django-views django-rest-framework

我正在尝试制作一个列出所有" Beat"我目前是朋友的对象。如何访问视图集内的用户以返回正确的对象?

模型:

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

3 个答案:

答案 0 :(得分:4)

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

但您的代码示例更复杂。 1)您不能将Battle对象与Beat个对象混合在一起。 2)您的序列化程序是Beat序列化程序,因此queryset必须是Beat个实例。

但是你可以在SQL中使用带有Beat原因的过滤器混合许多or来源,这样你就可以获得my_beats OR related_to_me的所有节拍。 Django有Q object允许复杂的查找。因此,您可以使用Q运算符OR加入两个|个对象。每个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)

答案 1 :(得分: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

答案 2 :(得分:0)

在序列化器中,

self.context["request"].user

例如:

class AsistenciaReunionSerializer(serializers.ModelSerializer):
    def create(self, validated_data):
        asistencia = AsistenciaReunion.objects.create(persona=validated_data["persona"],
                                                      reunion=validated_data["reunion"],
                                                      registrador=self.context["request"].user).save()
        return asistencia