Simplified model structure (I'm leaving out important bits, obviously, there are good reasons these are in different models):
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)
This stores whether interested people want to receive email offers, etc. We have a page where people can change these settings, which uses the hash to identify the person so people can't change other's settings, see who's signed up, etc. The values are fully alpha-numeric.
The view looks like this:
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()
So staff members can see and access all Contact
entries, but otherwise we'll return a queryset with one entry, the Contact
linked to a User
with an email_hash
that matches the ref
query param.
This passes all the unittests checking various combinations of staff and not, with and without the ref
query param, etc.
If I log into our remote environment and start a django shell, I can do the following:
>>> 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"}]}'
However, if you then make that exact same request from a browser or curl:
$ curl http://user-service-url/contact/?ref=a-valid-hash
{"count":0,"next":null,"previous":null,"results":[]}
We've disabled all kinds of caching, we're not going through any kind of proxy service, yet we repeatedly, but not consistently, get no results for "proper" requests, when all unittests and manual shell requests return the correct result.
Any suggestions of where to look? What other processing of data doesn't happen when requesting via a test request factory?