Extract get_object_by_lookup_fields method

Issue: HIC-178
Change-Id: I406ce8b8ca0b5dbec587a6786f820746240bc835
diff --git a/crashreports/rest_api_crashreports.py b/crashreports/rest_api_crashreports.py
index 30da54a..40a1adb 100644
--- a/crashreports/rest_api_crashreports.py
+++ b/crashreports/rest_api_crashreports.py
@@ -1,7 +1,6 @@
 """REST API for accessing crash reports."""
 from drf_yasg import openapi
 from drf_yasg.utils import swagger_auto_schema
-from django.shortcuts import get_object_or_404
 from django.utils.decorators import method_decorator
 from rest_framework import status, generics
 from rest_framework.response import Response
@@ -12,6 +11,7 @@
     SWAGGER_SECURITY_REQUIREMENTS_ALL,
 )
 from crashreports.serializers import CrashReportSerializer
+from crashreports.utils import get_object_by_lookup_fields
 from crashreports.models import Crashreport
 from crashreports.response_descriptions import default_desc
 
@@ -137,11 +137,4 @@
 
     def get_object(self):
         """Retrieve a crash report."""
-        queryset = self.get_queryset()
-        query_filter = {}
-        for field in self.multiple_lookup_fields:
-            if field in self.kwargs:
-                query_filter[field] = self.kwargs[field]
-        obj = get_object_or_404(queryset, **query_filter)
-        self.check_object_permissions(self.request, obj)
-        return obj
+        return get_object_by_lookup_fields(self, self.multiple_lookup_fields)
diff --git a/crashreports/rest_api_heartbeats.py b/crashreports/rest_api_heartbeats.py
index 33a6383..e5a718e 100644
--- a/crashreports/rest_api_heartbeats.py
+++ b/crashreports/rest_api_heartbeats.py
@@ -1,6 +1,5 @@
 """REST API for accessing heartbeats."""
 
-from django.shortcuts import get_object_or_404
 from django.utils.decorators import method_decorator
 from drf_yasg import openapi
 from drf_yasg.utils import swagger_auto_schema
@@ -14,6 +13,7 @@
 )
 from crashreports.response_descriptions import default_desc
 from crashreports.serializers import HeartBeatSerializer
+from crashreports.utils import get_object_by_lookup_fields
 
 
 @method_decorator(
@@ -104,11 +104,4 @@
 
     def get_object(self):
         """Retrieve a heartbeat."""
-        queryset = self.get_queryset()
-        query_filter = {}
-        for field in self.multiple_lookup_fields:
-            if field in self.kwargs:
-                query_filter[field] = self.kwargs[field]
-        obj = get_object_or_404(queryset, **query_filter)
-        self.check_object_permissions(self.request, obj)
-        return obj
+        return get_object_by_lookup_fields(self, self.multiple_lookup_fields)
diff --git a/crashreports/utils.py b/crashreports/utils.py
new file mode 100644
index 0000000..005499a
--- /dev/null
+++ b/crashreports/utils.py
@@ -0,0 +1,25 @@
+"""Utility functions for the crashreports app."""
+
+from django.shortcuts import get_object_or_404
+
+
+def get_object_by_lookup_fields(view, lookup_fields):
+    """Retrieve an object using the provided lookup fields.
+
+    Filter objects by the request parameters given in the view. Use only the
+    parameters that are given in the lookup field keys set. If a single
+    object instance matches the filters, it is returned. Otherwise a HTTP 404
+    exception is raised.
+
+    :param view: The view containing the request parameters.
+    :param lookup_fields: Set of keys of request parameters to use.
+    :return: The matched object.
+    """
+    queryset = view.get_queryset()
+    query_filter = {}
+    for field in lookup_fields:
+        if field in view.kwargs:
+            query_filter[field] = view.kwargs[field]
+    obj = get_object_or_404(queryset, **query_filter)
+    view.check_object_permissions(view.request, obj)
+    return obj