Django Viewset在shell / tests和实际请求之间返回不同的数据

时间:2018-05-17 10:24:32

标签: django django-rest-framework django-views django-rest-viewsets

简化的模型结构(我遗漏了重要的部分,显然,这些都有很好的理由在不同的模型中):

class Contact(models.Model):
    receive_marketing = models.DateTimeField(null=True, blank=True)

class User(models.Model):
    email_hash = models.CharField(max_length=255)
    contact = models.ForeignKey(Contact)

存储感兴趣的人是否想要接收电子邮件优惠等。 我们有一个页面,人们可以更改这些设置,使用哈希来识别此人,这样人们就无法更改其他人的设置,查看谁注册了等等。这些值完全是字母数字。

视图如下所示:

class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    permission_classes = (AllowAny, )

    def get_queryset(self):
        if self.request.user.is_staff:
            return ContactViewSet.queryset

        token = self.request.query_params.get('ref')
        return Contact.objects.filter(user__email_hash__isnull=False,
                                      user__email_hash=token).distinct()

因此,工作人员可以查看和访问所有Contact个条目,否则我们将返回一个包含一个条目的查询集,Contact链接到Useremail_hash }匹配ref查询参数。

这会通过检查各种工作人员组合的所有单元测试,有没有ref查询参数等。

如果我登录我们的远程环境并启动django shell,我可以执行以下操作:

>>> from user.views import ContactViewSet
>>> from rest_framework.test import APIRequestFactory
>>> factory = APIRequestFactory()
>>> view = ContactViewSet.as_view({'get': 'list'})
>>> request = factory.get('/contact/?ref=a-valid-hash')
>>> view(request).rendered_content
b'{"count":1,"next":null,"previous":null,"results":[{"id":222,"receive_marketing":"2018-05-15T14:11:13.449719Z"}]}'

但是,如果您从浏览器或卷曲中提出完全相同的请求:

$ curl http://user-service-url/contact/?ref=a-valid-hash
{"count":0,"next":null,"previous":null,"results":[]}

我们已禁用所有类型的缓存,我们不会通过任何类型的代理服务,但是当所有单元测试和手动shell请求返回时,我们反复但不一致地得不到“正确”请求的结果正确的结果。

有什么建议吗?通过测试请求工厂请求时,不会发生哪些其他数据处理?

2 个答案:

答案 0 :(得分:0)

测试请求工厂中似乎缺少用户身份验证,因此无需任何过滤器即可获取用户身份验证。在 self.request.user

中为用户对象设置了什么值

或者可能 ref 值未正确设置。

答案 1 :(得分:0)

原来问题出现在Serializer中,它已经指定了一个Policy类。不知道为什么有一个关于序列化器的政策使得它有时没有返回结果,有时候会返回正确的结果,但是花了四天时间我就不在乎了,我很高兴它的工作原理。