'Internal helper function to return fields of the model.
* If forward=True, then fields defined on this model are returned.
* If reverse=True, then relations pointing to this model are returned.
* If include_hidden=True, then fields with is_hidden=True are returned.
* The include_parents argument toggles if fields from parent models
should be included. It has three values: True, False, and
PROXY_PARENTS. When set to PROXY_PARENTS, the call will return all
fields defined for the current model or any of its parents in the
parent chain to the model\'s concrete model.'

def _get_fields(self, forward=True, reverse=True, include_parents=True, include_hidden=False, seen_models=None):

    if (include_parents not in (True, False, PROXY_PARENTS)):
        raise TypeError(('Invalid    argument    for    include_parents:    %s' % (include_parents,)))
    topmost_call = False
    if (seen_models is None):
        seen_models = set()
        topmost_call = True
    seen_models.add(self.model)
    cache_key = (forward, reverse, include_parents, include_hidden, topmost_call)
    with suppress(KeyError):
        return self._get_fields_cache[cache_key]
    fields = []
    if (include_parents is not False):
        for parent in self.parents:
            if (parent in seen_models):
                continue
            if ((parent._meta.concrete_model != self.concrete_model) and (include_parents == PROXY_PARENTS)):
                continue
            for obj in parent._meta._get_fields(forward=forward, reverse=reverse, include_parents=include_parents, include_hidden=include_hidden, seen_models=seen_models):
                if (getattr(obj, 'parent_link', False) and (obj.model != self.concrete_model)):
                    continue
                fields.append(obj)
    if (reverse and (not self.proxy)):
        all_fields = self._relation_tree
        for field in all_fields:
            if (include_hidden or (not field.remote_field.hidden)):
                fields.append(field.remote_field)
    if forward:
        fields.extend((field for field in chain(self.local_fields, self.local_many_to_many)))
        if topmost_call:
            fields.extend((f for f in self.private_fields))
    fields = make_immutable_fields_list('get_fields()', fields)
    self._get_fields_cache[cache_key] = fields
    return fields
