'Create object from Django request and response objects
If an explicit Request ``payload`` is not specified, the payload will be
determined directly from the Request object. This makes a good effort to
normalize the data, however we don\'t enforce that the payload is JSON
:param req: Request object to store
:type req: HttpRequest
:param resp: Response object to store
:type resp: HttpResponse
:param related_object: Object to use for generic relation
:param payload: Alternate payload object to store
:type payload: dict'

@transaction.atomic
def from_exchange(self, req, resp, related_object, payload=None):

    request_payload = payload
    if (request_payload is None):
        request_payload = normalize_request_payload(req)
    try:
        request_body = json.dumps(request_payload, sort_keys=True)
    except TypeError:
        request_body = str(request_payload)
    request_headers = dict(((key[5:].title().replace('_', '-'), str(val)) for (key, val) in list(req.META.items()) if key.startswith('HTTP_')))
    request_headers['Content-Type'] = req.content_type
    for filter_rule in self.REQ_FILTER_RULES:
        for key in list(request_headers.keys()):
            if filter_rule.match(key):
                del request_headers[key]
    response_payload = (resp.data if hasattr(resp, 'data') else resp.content)
    try:
        response_body = json.dumps(response_payload, sort_keys=True)
    except TypeError:
        response_body = str(response_payload)
    response_headers = dict(list(resp.items()))
    fields = {'status_code': resp.status_code, 'request_headers': request_headers, 'request_body': request_body, 'response_body': response_body, 'response_headers': response_headers}
    fields['related_object'] = related_object
    obj = self.create(**fields)
    self.delete_limit(related_object)
    return obj
