def test_bad_external_id(self): """ Test when a bad external ID is given, an ObjectDoesNotExist is raised. The exist DoestNotExist is inferred from the model. """ with self.assertRaises(models.CarModel.DoesNotExist): utils.internal_id_from_model_and_external_id( models.CarModel, "bad data")
def test_external_id_for_different_model(self): """ Test if the external ID doesn't match the model, we raise an exception. """ ct_org = ContentType.objects.get_for_model(models.Organization) org = models.Organization.objects.create(name='a') external_id = utils.get_hash_ids_source().encode(ct_org.pk, org.pk) # We external ID does match an internal ID, but not for this Model. with self.assertRaises(models.CarModel.DoesNotExist): utils.internal_id_from_model_and_external_id( models.CarModel, external_id)
def test_returns_valid_internal_id(self): """ Test valid Model/External ID combinations return internal IDs. The external ID is composed of the primary keys for the instance and the model's ContentType. """ ct_org = ContentType.objects.get_for_model(models.Organization) org_a = models.Organization.objects.create(name='a') org_b = models.Organization.objects.create(name='b') external_id_a = utils.get_hash_ids_source().encode(ct_org.pk, org_a.pk) self.assertEqual( org_a.pk, utils.internal_id_from_model_and_external_id( models.Organization, external_id_a)) external_id_b = utils.get_hash_ids_source().encode(ct_org.pk, org_b.pk) self.assertEqual( org_b.pk, utils.internal_id_from_model_and_external_id( models.Organization, external_id_b))
def move_thread(self, request, pk=None): thread = self.get_object() print(request.data) if 'forum' in request.data: forum = Forum.objects.get( id=internal_id_from_model_and_external_id( Forum, request.data['forum'])) if forum: thread.forum = forum thread.save() return Response({}, status=status.HTTP_200_OK) else: return Response({}, status=status.HTTP_404_NOT_FOUND) else: return Response({}, status=status.HTTP_400_BAD_REQUEST)
def ban_user(self, request, username=None): user = self.get_object() if request.data['post']: post = Post.objects.get(pk=internal_id_from_model_and_external_id( Post, request.data['post'])) ban_reason = BanReason( post=post, ban_reason=request.data['ban_reason'], banner=request.user, banned_user=post.creator, ban_expiry_date=request.data['ban_expiry_date']) ban_reason.save() return Response(serializers.BanReasonSerializer(ban_reason).data, status=status.HTTP_200_OK) return Response({}, status=status.HTTP_400_BAD_REQUEST)
def get_object(self): """ Extend the vanilla get_object() method to retrieve by external_id. Translate the external ID to the internal one explicitly, rather than calling get_by_external_id() in order to allow for additional filtering. """ queryset = self.filter_queryset(self.get_queryset()) # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg)) assert self.lookup_field == 'pk', ( 'View %s cannot have a custom lookup_field value, as the ' 'ExternalIdViewMixin expects to retrieve the object by its ' 'primary key.' % (self.__class__.__name__)) try: internal_id = utils.internal_id_from_model_and_external_id( queryset.model, self.kwargs[lookup_url_kwarg]) except ObjectDoesNotExist: raise Http404 obj = get_object_or_404(queryset, pk=internal_id) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
def to_internal_value(self, value): model = self.get_model() try: return utils.internal_id_from_model_and_external_id(model, value) except ObjectDoesNotExist: self.fail('malformed_hash_id')