Django REST过滤器通过外键lookup_field查询

时间:2019-03-04 05:00:17

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

我有一个时间obj序列化为DRF。

型号:

class Time(TimeStampedModel):
    user = models.ForeignKey(
        'users.User', on_delete=models.CASCADE, related_name='time_logs')
    amount = models.DurationField()
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

序列化器:

class TimeSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Time
        fields = ('__all__')
        extra_kwargs = {'date_created': {'read_only': True}, 'date_updated': {'read_only': True}}

视图集:

class UserTimeViewSet(viewsets.ModelViewSet):
    serializer_class = TimeSerializer
    queryset = Time.objects.all()

    def get_queryset(self):
        return Time.objects.filter(user=self.request.user)

网址

from rest_framework.routers import DefaultRouter

router = DefaultRouter()

router.register(r'users/time', UserTimeViewSet)

这给了我一个端点:/users/time/{id},其中{id}是时间obj id。当我尝试将端点修改为相同的url路由,而是通过在序列化程序和ViewSet上覆盖lookup_field来将其用户名作为arg传递给arg(仅获得该用户的时间)时,我要么得到响应错误或{"detail":"Not found."}

class UserTimeViewSet(viewsets.ModelViewSet):
    serializer_class = TimeSerializer
    queryset = Time.objects.all().select_related('user')
    lookup_field = 'user'

也尝试过:

class UserTimeViewSet(generics.ListAPIView):
    serializer_class = TimeSerializer

    def get_queryset(self):
        user = self.kwargs['user']
        return Time.objects.filter(user=user)

如何通过用户ID获取与用户的关系时间?

2 个答案:

答案 0 :(得分:2)

如果我理解正确,那么这个视图类将起到神奇作用

class UserTimeViewSet(viewsets.ModelViewSet):
    serializer_class = TimeSerializer
    queryset = Time.objects.all()
    lookup_field = 'user' # add "lookup_field" attribute

    # remove "get_queryset()" method
    def get_queryset(self):
        return Time.objects.filter(user=self.request.user)

答案 1 :(得分:0)

如果用户只有一个Time对象,则

JPG的另一个答案是有效的解决方案。但是,多个objs将返回MultipleObjectsReturned get() returned more than one Time错误

多个obj的解决方案是将视图集转换为ListAPIView:

观看次数:

class UserTimeViewSet(generics.ListAPIView):
    serializer_class = TimeSerializer
    queryset = Time.objects.all()

    def get_queryset(self):
        return Time.objects.filter(user=self.kwargs['user'])

网址:

url(r'users/time/(?P<user>\d+)/$', UserTimeViewSet.as_view(), name='user_time'),