human
Complete this python program:
def json_encode(data, *args, **kwargs):
assistant
#Here is the Python program you requested.

    """The main issues with django\s default json serializer is that properties that
    had been added to an object dynamically are being ignored (and it also has
    problems with some models).
    """
    def _any(data):
        ret = None
        if hasattr(data, 'canonical'):
            ret = _any(data.canonical())
        elif isinstance(data, list):
            ret = _list(data)
        elif isinstance(data, set):
            ret = _list(list(data))
        elif isinstance(data, dict):
            ret = _dict(data)
        elif isinstance(data, (Decimal, ObjectId)):
            ret = str(data)
        elif isinstance(data, models.query.QuerySet):
            ret = _list(data)
        elif isinstance(data, MongoQuerySet):
            ret = _list(data)
        elif isinstance(data, models.Model):
            ret = _model(data)
        elif isinstance(data, basestring):
            ret = smart_unicode(data)
        elif isinstance(data, Exception):
            ret = unicode(data)
        elif isinstance(data, Promise):
            ret = force_unicode(data)
        elif (isinstance(data, datetime.datetime) or isinstance(data, datetime.date)):
            ret = str(data)
        elif hasattr(data, 'to_json'):
            ret = data.to_json()
        else:
            ret = data
        return ret
    def _model(data):
        ret = {}
        for f in data._meta.fields:
            ret[f.attname] = _any(getattr(data, f.attname))
        fields = (dir(data.__class__) + ret.keys())
        add_ons = [k for k in dir(data) if (k not in fields)]
        for k in add_ons:
            ret[k] = _any(getattr(data, k))
        return ret
    def _list(data):
        ret = []
        for v in data:
            ret.append(_any(v))
        return ret
    def _dict(data):
        ret = {}
        for (k, v) in data.items():
            ret[str(k)] = _any(v)
        return ret
    if hasattr(data, 'to_json'):
        data = data.to_json()
    ret = _any(data)
    return json.dumps(ret)