【问题标题】:DjangoRestFramework how to get user in viewsetDjangoRestFramework如何让用户进入视图
【发布时间】:2016-04-30 08:28:25
【问题描述】:

我正在尝试创建一个好友供稿,其中列出了我目前与之成为好友的所有“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,)

【问题讨论】:

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


    【解决方案1】:

    您的问题的直接答案很简单:覆盖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)
    

    【讨论】:

      【解决方案2】:

      您应该像这样覆盖序列化程序(逻辑所属的位置)中的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
      

      【讨论】:

        【解决方案3】:

        在序列化器中,

        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
        

        【讨论】:

          猜你喜欢
          • 2015-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-03
          • 1970-01-01
          • 2021-04-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多